2009-10-12 03:35:35 +00:00
/*
* PROJECT : ReactOS Kernel
2013-06-26 12:24:55 +00:00
* LICENSE : GPL v2 - See COPYING in the top level directory
2009-10-12 03:35:35 +00:00
* FILE : ntoskrnl / fsrtl / largemcb . c
2012-02-29 09:18:01 +00:00
* PURPOSE : Large Mapped Control Block ( MCB ) support for File System Drivers
2013-06-26 12:24:55 +00:00
* PROGRAMMERS : Aleksey Bragin < aleksey @ reactos . org >
* Jan Kratochvil < project - captive @ jankratochvil . net >
2016-05-26 16:35:45 +00:00
* Trevor Thompson
2009-10-12 03:35:35 +00:00
*/
/* INCLUDES ******************************************************************/
# include <ntoskrnl.h>
2013-06-26 12:24:55 +00:00
# define NDEBUG
2009-10-12 03:35:35 +00:00
# include <debug.h>
2013-06-26 12:24:55 +00:00
# define MIN(x,y) (((x)<(y))?(x):(y))
# define MAX(x,y) (((x)>(y))?(x):(y))
2012-02-29 09:18:01 +00:00
/* GLOBALS *******************************************************************/
PAGED_LOOKASIDE_LIST FsRtlFirstMappingLookasideList ;
NPAGED_LOOKASIDE_LIST FsRtlFastMutexLookasideList ;
2013-06-26 12:24:55 +00:00
/* We use only real 'mapping' runs; we do not store 'holes' to our GTree. */
typedef struct _LARGE_MCB_MAPPING_ENTRY // run
2012-02-29 09:18:01 +00:00
{
2013-04-29 10:28:58 +00:00
LARGE_INTEGER RunStartVbn ;
2013-06-26 12:24:55 +00:00
LARGE_INTEGER RunEndVbn ; /* RunStartVbn+SectorCount; that means +1 after the last sector */
LARGE_INTEGER StartingLbn ; /* Lbn of 'RunStartVbn' */
2012-02-29 09:18:01 +00:00
} LARGE_MCB_MAPPING_ENTRY , * PLARGE_MCB_MAPPING_ENTRY ;
2013-06-26 12:24:55 +00:00
typedef struct _LARGE_MCB_MAPPING // mcb_priv
2013-04-29 10:10:44 +00:00
{
RTL_GENERIC_TABLE Table ;
} LARGE_MCB_MAPPING , * PLARGE_MCB_MAPPING ;
typedef struct _BASE_MCB_INTERNAL {
ULONG MaximumPairCount ;
ULONG PairCount ;
USHORT PoolType ;
USHORT Flags ;
PLARGE_MCB_MAPPING Mapping ;
} BASE_MCB_INTERNAL , * PBASE_MCB_INTERNAL ;
2016-05-26 16:35:45 +00:00
/*
2013-06-26 12:24:55 +00:00
static LARGE_MCB_MAPPING_ENTRY StaticRunBelow0 = {
2016-05-26 16:35:45 +00:00
{ { - 1 } } , // ignored
2013-06-26 12:24:55 +00:00
{ { 0 } } ,
2016-05-26 16:35:45 +00:00
{ { - 1 } } , // ignored
2013-06-26 12:24:55 +00:00
} ;
2016-05-26 16:35:45 +00:00
*/
2013-06-26 12:24:55 +00:00
2012-02-29 09:18:01 +00:00
static PVOID NTAPI McbMappingAllocate ( PRTL_GENERIC_TABLE Table , CLONG Bytes )
{
2013-04-29 10:28:58 +00:00
PVOID Result ;
PBASE_MCB Mcb = ( PBASE_MCB ) Table - > TableContext ;
2019-11-01 18:05:20 +00:00
Result = ExAllocatePoolWithTag ( Mcb - > PoolType , Bytes , ' BCML ' ) ;
2013-08-31 16:02:13 +00:00
DPRINT ( " McbMappingAllocate(%lu) => %p \n " , Bytes , Result ) ;
2013-04-29 10:28:58 +00:00
return Result ;
2012-02-29 09:18:01 +00:00
}
static VOID NTAPI McbMappingFree ( PRTL_GENERIC_TABLE Table , PVOID Buffer )
{
2013-04-29 10:28:58 +00:00
DPRINT ( " McbMappingFree(%p) \n " , Buffer ) ;
2019-11-01 18:05:20 +00:00
ExFreePoolWithTag ( Buffer , ' BCML ' ) ;
2012-02-29 09:18:01 +00:00
}
2013-06-26 12:24:55 +00:00
static
RTL_GENERIC_COMPARE_RESULTS
NTAPI
McbMappingCompare ( PRTL_GENERIC_TABLE Table ,
PVOID PtrA ,
PVOID PtrB )
2012-02-29 09:18:01 +00:00
{
2013-04-29 10:28:58 +00:00
PLARGE_MCB_MAPPING_ENTRY A = PtrA , B = PtrB ;
2013-06-26 12:24:55 +00:00
RTL_GENERIC_COMPARE_RESULTS Res ;
2013-04-29 10:28:58 +00:00
2014-11-13 20:11:05 +00:00
ASSERT ( A ) ;
ASSERT ( B ) ;
2013-06-26 12:24:55 +00:00
2014-11-13 20:11:05 +00:00
if ( A - > RunStartVbn . QuadPart = = B - > RunStartVbn . QuadPart & & A - > RunEndVbn . QuadPart = = B - > RunEndVbn . QuadPart )
Res = GenericEqual ;
else if ( A - > RunEndVbn . QuadPart < = B - > RunStartVbn . QuadPart )
2013-06-26 12:24:55 +00:00
Res = GenericLessThan ;
2014-11-13 20:11:05 +00:00
else if ( A - > RunEndVbn . QuadPart > = B - > RunStartVbn . QuadPart )
2013-06-26 12:24:55 +00:00
Res = GenericGreaterThan ;
else
{
2014-11-13 20:11:05 +00:00
ASSERT ( FALSE ) ;
Res = GenericEqual ;
2013-06-26 12:24:55 +00:00
}
return Res ;
}
static RTL_GENERIC_COMPARE_RESULTS NTAPI McbMappingIntersectCompare ( PRTL_GENERIC_TABLE Table , PVOID PtrA , PVOID PtrB )
{
2014-11-13 20:11:05 +00:00
PLARGE_MCB_MAPPING_ENTRY A = PtrA , B = PtrB ;
2013-06-26 12:24:55 +00:00
RTL_GENERIC_COMPARE_RESULTS Res ;
2014-11-13 20:11:05 +00:00
if ( A - > RunStartVbn . QuadPart < = B - > RunStartVbn . QuadPart & & A - > RunEndVbn . QuadPart > B - > RunStartVbn . QuadPart )
Res = GenericEqual ;
else if ( A - > RunStartVbn . QuadPart > = B - > RunStartVbn . QuadPart & & B - > RunEndVbn . QuadPart > A - > RunStartVbn . QuadPart )
Res = GenericEqual ;
else if ( A - > RunStartVbn . QuadPart < B - > RunStartVbn . QuadPart )
Res = GenericLessThan ;
else if ( A - > RunStartVbn . QuadPart > B - > RunStartVbn . QuadPart )
Res = GenericGreaterThan ;
else
Res = GenericEqual ;
2013-06-26 12:24:55 +00:00
2014-11-13 20:11:05 +00:00
return Res ;
2012-02-29 09:18:01 +00:00
}
2013-06-26 12:24:55 +00:00
2009-10-12 03:35:35 +00:00
/* PUBLIC FUNCTIONS **********************************************************/
/*
2012-02-29 09:18:01 +00:00
* @ implemented
2013-06-26 12:24:55 +00:00
* @ Mcb : # PLARGE_MCB initialized by FsRtlInitializeLargeMcb ( ) .
* % NULL value is forbidden .
* @ Vbn : Starting virtual block number of the wished range .
* @ Lbn : Starting logical block number of the wished range .
* @ SectorCount : Length of the wished range .
* Value less or equal to % 0 is forbidden ; FIXME : Is the reject of % 0 W32 compliant ?
*
* Adds the specified range @ Vbn . . . @ Vbn + @ SectorCount - 1 to @ Mcb .
* Any mappings previously in this range are deleted first .
*
* Returns : % TRUE if successful .
2012-02-29 09:18:01 +00:00
*/
BOOLEAN
NTAPI
2013-04-29 10:10:44 +00:00
FsRtlAddBaseMcbEntry ( IN PBASE_MCB OpaqueMcb ,
2012-02-29 09:18:01 +00:00
IN LONGLONG Vbn ,
IN LONGLONG Lbn ,
IN LONGLONG SectorCount )
{
2016-04-03 20:17:09 +00:00
BOOLEAN Result = TRUE ;
2016-04-11 20:29:35 +00:00
BOOLEAN IntResult ;
2013-04-29 10:10:44 +00:00
PBASE_MCB_INTERNAL Mcb = ( PBASE_MCB_INTERNAL ) OpaqueMcb ;
2013-06-26 12:24:55 +00:00
LARGE_MCB_MAPPING_ENTRY Node , NeedleRun ;
2014-11-13 20:11:05 +00:00
PLARGE_MCB_MAPPING_ENTRY LowerRun , HigherRun ;
2013-06-26 12:24:55 +00:00
BOOLEAN NewElement ;
2020-11-30 11:42:33 +00:00
LONGLONG IntLbn , IntSectorCount ;
2013-06-26 12:24:55 +00:00
2016-04-03 20:17:09 +00:00
DPRINT ( " FsRtlAddBaseMcbEntry(%p, %I64d, %I64d, %I64d) \n " , OpaqueMcb , Vbn , Lbn , SectorCount ) ;
if ( Vbn < 0 )
{
Result = FALSE ;
goto quit ;
}
if ( SectorCount < = 0 )
{
Result = FALSE ;
goto quit ;
}
2016-04-11 20:29:35 +00:00
2020-11-30 11:42:33 +00:00
IntResult = FsRtlLookupBaseMcbEntry ( OpaqueMcb , Vbn , & IntLbn , & IntSectorCount , NULL , NULL , NULL ) ;
2016-04-11 20:29:35 +00:00
if ( IntResult )
{
if ( IntLbn ! = - 1 & & IntLbn ! = Lbn )
{
Result = FALSE ;
goto quit ;
}
2020-11-30 11:42:33 +00:00
if ( ( IntLbn ! = - 1 ) & & ( IntSectorCount > = SectorCount ) )
{
/* This is a no-op */
goto quit ;
}
2016-04-11 20:29:35 +00:00
}
2013-06-26 12:24:55 +00:00
/* clean any possible previous entries in our range */
FsRtlRemoveBaseMcbEntry ( OpaqueMcb , Vbn , SectorCount ) ;
// We need to map [Vbn, Vbn+SectorCount) to [Lbn, Lbn+SectorCount),
// taking in account the fact that we need to merge these runs if
// they are adjacent or overlap, but fail if new run fully fits into another run
2013-04-29 10:28:58 +00:00
2013-06-26 12:24:55 +00:00
/* initially we think we will be inserted as a separate run */
2013-04-29 10:28:58 +00:00
Node . RunStartVbn . QuadPart = Vbn ;
2013-06-26 12:24:55 +00:00
Node . RunEndVbn . QuadPart = Vbn + SectorCount ;
2013-04-29 10:28:58 +00:00
Node . StartingLbn . QuadPart = Lbn ;
2013-06-26 12:24:55 +00:00
/* optionally merge with lower run */
NeedleRun . RunStartVbn . QuadPart = Node . RunStartVbn . QuadPart - 1 ;
NeedleRun . RunEndVbn . QuadPart = NeedleRun . RunStartVbn . QuadPart + 1 ;
2014-11-13 20:11:05 +00:00
NeedleRun . StartingLbn . QuadPart = ~ 0ULL ;
2013-06-26 12:24:55 +00:00
Mcb - > Mapping - > Table . CompareRoutine = McbMappingIntersectCompare ;
2016-04-10 10:29:28 +00:00
if ( ( LowerRun = RtlLookupElementGenericTable ( & Mcb - > Mapping - > Table , & NeedleRun ) ) & &
2016-04-15 20:50:40 +00:00
( LowerRun - > StartingLbn . QuadPart + ( LowerRun - > RunEndVbn . QuadPart - LowerRun - > RunStartVbn . QuadPart ) = = Node . StartingLbn . QuadPart ) )
2013-04-29 10:28:58 +00:00
{
2013-06-26 12:24:55 +00:00
ASSERT ( LowerRun - > RunEndVbn . QuadPart = = Node . RunStartVbn . QuadPart ) ;
Node . RunStartVbn . QuadPart = LowerRun - > RunStartVbn . QuadPart ;
2014-11-13 20:11:05 +00:00
Node . StartingLbn . QuadPart = LowerRun - > StartingLbn . QuadPart ;
2013-06-26 12:24:55 +00:00
Mcb - > Mapping - > Table . CompareRoutine = McbMappingCompare ;
RtlDeleteElementGenericTable ( & Mcb - > Mapping - > Table , LowerRun ) ;
2016-04-18 20:49:14 +00:00
- - Mcb - > PairCount ;
2013-06-26 12:24:55 +00:00
DPRINT ( " Intersecting lower run found (%I64d,%I64d) Lbn: %I64d \n " , LowerRun - > RunStartVbn . QuadPart , LowerRun - > RunEndVbn . QuadPart , LowerRun - > StartingLbn . QuadPart ) ;
2013-04-29 10:28:58 +00:00
}
2013-06-26 12:24:55 +00:00
/* optionally merge with higher run */
NeedleRun . RunStartVbn . QuadPart = Node . RunEndVbn . QuadPart ;
NeedleRun . RunEndVbn . QuadPart = NeedleRun . RunStartVbn . QuadPart + 1 ;
Mcb - > Mapping - > Table . CompareRoutine = McbMappingIntersectCompare ;
2016-04-10 10:29:28 +00:00
if ( ( HigherRun = RtlLookupElementGenericTable ( & Mcb - > Mapping - > Table , & NeedleRun ) ) & &
( Node . StartingLbn . QuadPart < = HigherRun - > StartingLbn . QuadPart ) )
2013-06-26 12:24:55 +00:00
{
ASSERT ( HigherRun - > RunStartVbn . QuadPart = = Node . RunEndVbn . QuadPart ) ;
Node . RunEndVbn . QuadPart = HigherRun - > RunEndVbn . QuadPart ;
Mcb - > Mapping - > Table . CompareRoutine = McbMappingCompare ;
RtlDeleteElementGenericTable ( & Mcb - > Mapping - > Table , HigherRun ) ;
2016-04-18 20:49:14 +00:00
- - Mcb - > PairCount ;
2013-06-26 12:24:55 +00:00
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 */
2014-11-13 20:11:05 +00:00
RtlInsertElementGenericTable ( & Mcb - > Mapping - > Table , & Node , sizeof ( Node ) , & NewElement ) ;
2016-04-19 06:25:18 +00:00
+ + Mcb - > PairCount ;
2013-06-26 12:24:55 +00:00
ASSERT ( NewElement ) ;
// NB: Two consecutive runs can only be merged, if actual LBNs also match!
/* 1.
Existing - > RunStartVbn
|
| ///////|
| /////////////|
|
Node - > RunStartVbn
2.
Existing - > RunStartVbn
|
| ///////|
| //////|
|
Node - > RunStartVbn
3.
Existing - > RunStartVbn
|
| ///////|
| ///|
|
Node - > RunStartVbn
4.
Existing - > RunStartVbn
|
| ///////|
| ///////////////|
|
Node - > RunStartVbn
Situation with holes :
1. Holes at both ends
2. Hole at the right , new run merged with the previous run
3. Hole at the right , new run is not merged with the previous run
4. Hole at the left , new run merged with the next run
5. Hole at the left , new run is not merged with the next run
6. No holes , exact fit to merge with both previous and next runs
7. No holes , merges only with the next run
8. No holes , merges only with the previous run
9. No holes , does not merge with next or prev runs
Overwriting existing mapping is not possible and results in FALSE being returned
*/
2016-04-03 20:17:09 +00:00
quit :
DPRINT ( " FsRtlAddBaseMcbEntry(%p, %I64d, %I64d, %I64d) = %d \n " , Mcb , Vbn , Lbn , SectorCount , Result ) ;
return Result ;
2012-02-29 09:18:01 +00:00
}
/*
* @ implemented
2009-10-12 03:35:35 +00:00
*/
BOOLEAN
NTAPI
FsRtlAddLargeMcbEntry ( IN PLARGE_MCB Mcb ,
IN LONGLONG Vbn ,
IN LONGLONG Lbn ,
IN LONGLONG SectorCount )
{
2012-02-29 09:18:01 +00:00
BOOLEAN Result ;
2016-04-03 20:17:09 +00:00
DPRINT ( " FsRtlAddLargeMcbEntry(%p, %I64d, %I64d, %I64d) \n " , Mcb , Vbn , Lbn , SectorCount ) ;
2012-02-29 09:18:01 +00:00
KeAcquireGuardedMutex ( Mcb - > GuardedMutex ) ;
Result = FsRtlAddBaseMcbEntry ( & ( Mcb - > BaseMcb ) ,
Vbn ,
Lbn ,
SectorCount ) ;
KeReleaseGuardedMutex ( Mcb - > GuardedMutex ) ;
2016-04-03 20:17:09 +00:00
DPRINT ( " FsRtlAddLargeMcbEntry(%p, %I64d, %I64d, %I64d) = %d \n " , Mcb , Vbn , Lbn , SectorCount , Result ) ;
2012-02-29 09:18:01 +00:00
return Result ;
2009-10-12 03:35:35 +00:00
}
/*
2013-06-26 12:24:55 +00:00
* @ implemented
* @ Mcb : # PLARGE_MCB initialized by FsRtlInitializeLargeMcb ( ) .
* % NULL value is forbidden .
* @ RunIndex : Requested range index to retrieve .
* @ Vbn : Returns the starting virtual block number of the wished range .
* % NULL pointer is forbidden .
* @ Lbn : Returns the starting logical block number of the wished range ( or - 1 if it is a hole ) .
* % NULL pointer is forbidden .
* @ SectorCount : Returns the length of the wished range .
* % NULL pointer is forbidden .
* Value less or equal to % 0 is forbidden ; FIXME : Is the reject of % 0 W32 compliant ?
*
* Retrieves the parameters of the specified run with index @ RunIndex .
2020-11-30 11:42:33 +00:00
*
2013-06-26 12:24:55 +00:00
* Mapping % 0 always starts at virtual block % 0 , either as ' hole ' or as ' real ' mapping .
* libcaptive does not store ' hole ' information to its # GTree .
* Last run is always a ' real ' run . ' hole ' runs appear as mapping to constant @ Lbn value % - 1.
*
* Returns : % TRUE if successful .
2009-10-12 03:35:35 +00:00
*/
BOOLEAN
NTAPI
2013-04-29 10:10:44 +00:00
FsRtlGetNextBaseMcbEntry ( IN PBASE_MCB OpaqueMcb ,
2016-05-26 16:35:45 +00:00
IN ULONG RunIndex ,
OUT PLONGLONG Vbn ,
OUT PLONGLONG Lbn ,
OUT PLONGLONG SectorCount )
2009-10-12 03:35:35 +00:00
{
2016-04-03 20:17:09 +00:00
BOOLEAN Result = FALSE ;
2013-04-29 10:10:44 +00:00
PBASE_MCB_INTERNAL Mcb = ( PBASE_MCB_INTERNAL ) OpaqueMcb ;
2016-05-26 16:35:45 +00:00
PLARGE_MCB_MAPPING_ENTRY Run = NULL ;
ULONG CurrentIndex = 0 ;
ULONGLONG LastVbn = 0 ;
ULONGLONG LastSectorCount = 0 ;
2016-04-03 20:17:09 +00:00
2020-11-30 11:42:33 +00:00
// Traverse the tree
2013-06-26 12:24:55 +00:00
for ( Run = ( PLARGE_MCB_MAPPING_ENTRY ) RtlEnumerateGenericTable ( & Mcb - > Mapping - > Table , TRUE ) ;
2016-05-26 16:35:45 +00:00
Run ;
2013-06-26 12:24:55 +00:00
Run = ( PLARGE_MCB_MAPPING_ENTRY ) RtlEnumerateGenericTable ( & Mcb - > Mapping - > Table , FALSE ) )
2013-04-29 10:28:58 +00:00
{
2016-05-26 16:35:45 +00:00
// is the current index a hole?
if ( Run - > RunStartVbn . QuadPart > ( LastVbn + LastSectorCount ) )
2013-06-26 12:24:55 +00:00
{
2016-05-26 16:35:45 +00:00
// Is this the index we're looking for?
if ( RunIndex = = CurrentIndex )
2013-06-26 12:24:55 +00:00
{
2016-05-26 16:35:45 +00:00
* Vbn = LastVbn + LastSectorCount ;
* Lbn = - 1 ;
* SectorCount = Run - > RunStartVbn . QuadPart - * Vbn ;
Result = TRUE ;
goto quit ;
2013-06-26 12:24:55 +00:00
}
2016-05-26 16:35:45 +00:00
CurrentIndex + + ;
2013-06-26 12:24:55 +00:00
}
2016-05-26 16:35:45 +00:00
if ( RunIndex = = CurrentIndex )
{
* Vbn = Run - > RunStartVbn . QuadPart ;
* Lbn = Run - > StartingLbn . QuadPart ;
* SectorCount = Run - > RunEndVbn . QuadPart - Run - > RunStartVbn . QuadPart ;
2013-06-26 12:24:55 +00:00
2016-05-26 16:35:45 +00:00
Result = TRUE ;
goto quit ;
}
2013-06-26 12:24:55 +00:00
2016-05-26 16:35:45 +00:00
CurrentIndex + + ;
LastVbn = Run - > RunStartVbn . QuadPart ;
LastSectorCount = Run - > RunEndVbn . QuadPart - Run - > RunStartVbn . QuadPart ;
2013-06-26 12:24:55 +00:00
}
2016-04-03 20:17:09 +00:00
quit :
DPRINT ( " FsRtlGetNextBaseMcbEntry(%p, %d, %p, %p, %p) = %d (%I64d, %I64d, %I64d) \n " , Mcb , RunIndex , Vbn , Lbn , SectorCount , Result , * Vbn , * Lbn , * SectorCount ) ;
return Result ;
2009-10-12 03:35:35 +00:00
}
/*
2012-02-29 09:18:01 +00:00
* @ implemented
2009-10-12 03:35:35 +00:00
*/
BOOLEAN
NTAPI
FsRtlGetNextLargeMcbEntry ( IN PLARGE_MCB Mcb ,
IN ULONG RunIndex ,
OUT PLONGLONG Vbn ,
OUT PLONGLONG Lbn ,
OUT PLONGLONG SectorCount )
{
2012-02-29 09:18:01 +00:00
BOOLEAN Result ;
2016-04-03 20:17:09 +00:00
DPRINT ( " FsRtlGetNextLargeMcbEntry(%p, %d, %p, %p, %p) \n " , Mcb , RunIndex , Vbn , Lbn , SectorCount ) ;
2012-02-29 09:18:01 +00:00
KeAcquireGuardedMutex ( Mcb - > GuardedMutex ) ;
Result = FsRtlGetNextBaseMcbEntry ( & ( Mcb - > BaseMcb ) ,
RunIndex ,
Vbn ,
Lbn ,
SectorCount ) ;
KeReleaseGuardedMutex ( Mcb - > GuardedMutex ) ;
2016-04-03 20:17:09 +00:00
DPRINT ( " FsRtlGetNextLargeMcbEntry(%p, %d, %p, %p, %p) = %d (%I64d, %I64d, %I64d) \n " , Mcb , RunIndex , Vbn , Lbn , SectorCount , Result , * Vbn , * Lbn , * SectorCount ) ;
2012-02-29 09:18:01 +00:00
return Result ;
2009-10-12 03:35:35 +00:00
}
/*
* @ implemented
*/
2012-02-29 09:18:01 +00:00
VOID
2009-10-12 03:35:35 +00:00
NTAPI
2013-04-29 10:10:44 +00:00
FsRtlInitializeBaseMcb ( IN PBASE_MCB OpaqueMcb ,
2012-02-29 09:18:01 +00:00
IN POOL_TYPE PoolType )
2009-10-12 03:35:35 +00:00
{
2013-04-29 10:10:44 +00:00
PBASE_MCB_INTERNAL Mcb = ( PBASE_MCB_INTERNAL ) OpaqueMcb ;
2012-02-29 09:18:01 +00:00
if ( PoolType = = PagedPool )
{
Mcb - > Mapping = ExAllocateFromPagedLookasideList ( & FsRtlFirstMappingLookasideList ) ;
}
else
{
Mcb - > Mapping = ExAllocatePoolWithTag ( PoolType | POOL_RAISE_IF_ALLOCATION_FAILURE ,
2013-04-29 10:28:58 +00:00
sizeof ( LARGE_MCB_MAPPING ) ,
2019-11-01 18:05:20 +00:00
' CBSF ' ) ;
2012-02-29 09:18:01 +00:00
}
Mcb - > PoolType = PoolType ;
2013-06-26 12:24:55 +00:00
Mcb - > PairCount = 0 ;
2012-02-29 09:18:01 +00:00
Mcb - > MaximumPairCount = MAXIMUM_PAIR_COUNT ;
2013-04-29 10:28:58 +00:00
RtlInitializeGenericTable ( & Mcb - > Mapping - > Table ,
2013-06-20 12:38:55 +00:00
McbMappingCompare ,
2013-04-29 10:28:58 +00:00
McbMappingAllocate ,
McbMappingFree ,
Mcb ) ;
2009-10-12 03:35:35 +00:00
}
/*
2012-02-29 09:18:01 +00:00
* @ implemented
2009-10-12 03:35:35 +00:00
*/
VOID
NTAPI
FsRtlInitializeLargeMcb ( IN PLARGE_MCB Mcb ,
IN POOL_TYPE PoolType )
{
2016-04-03 20:17:09 +00:00
DPRINT ( " FsRtlInitializeLargeMcb(%p, %d) \n " , Mcb , PoolType ) ;
2012-02-29 09:18:01 +00:00
Mcb - > GuardedMutex = ExAllocateFromNPagedLookasideList ( & FsRtlFastMutexLookasideList ) ;
KeInitializeGuardedMutex ( Mcb - > GuardedMutex ) ;
_SEH2_TRY
{
FsRtlInitializeBaseMcb ( & ( Mcb - > BaseMcb ) , PoolType ) ;
}
_SEH2_EXCEPT ( EXCEPTION_EXECUTE_HANDLER )
{
ExFreeToNPagedLookasideList ( & FsRtlFastMutexLookasideList ,
Mcb - > GuardedMutex ) ;
Mcb - > GuardedMutex = NULL ;
}
_SEH2_END ;
2009-10-12 03:35:35 +00:00
}
/*
* @ implemented
*/
2020-10-06 19:44:01 +00:00
CODE_SEG ( " INIT " )
2009-10-12 03:35:35 +00:00
VOID
NTAPI
2012-02-29 09:18:01 +00:00
FsRtlInitializeLargeMcbs ( VOID )
2009-10-12 03:35:35 +00:00
{
2012-02-29 09:18:01 +00:00
/* Initialize the list for the MCB */
ExInitializePagedLookasideList ( & FsRtlFirstMappingLookasideList ,
NULL ,
NULL ,
POOL_RAISE_IF_ALLOCATION_FAILURE ,
2013-04-29 10:28:58 +00:00
sizeof ( LARGE_MCB_MAPPING ) ,
2012-02-29 09:18:01 +00:00
IFS_POOL_TAG ,
0 ) ; /* FIXME: Should be 4 */
/* Initialize the list for the guarded mutex */
ExInitializeNPagedLookasideList ( & FsRtlFastMutexLookasideList ,
NULL ,
NULL ,
POOL_RAISE_IF_ALLOCATION_FAILURE ,
sizeof ( KGUARDED_MUTEX ) ,
IFS_POOL_TAG ,
0 ) ; /* FIXME: Should be 32 */
2009-10-12 03:35:35 +00:00
}
/*
2016-05-26 16:35:45 +00:00
* @ implemented
2009-10-12 03:35:35 +00:00
*/
BOOLEAN
NTAPI
2013-04-29 10:10:44 +00:00
FsRtlLookupBaseMcbEntry ( IN PBASE_MCB OpaqueMcb ,
2016-05-26 16:35:45 +00:00
IN LONGLONG Vbn ,
OUT PLONGLONG Lbn OPTIONAL ,
OUT PLONGLONG SectorCountFromLbn OPTIONAL ,
OUT PLONGLONG StartingLbn OPTIONAL ,
OUT PLONGLONG SectorCountFromStartingLbn OPTIONAL ,
OUT PULONG Index OPTIONAL )
2012-02-29 09:18:01 +00:00
{
2016-04-03 20:17:09 +00:00
BOOLEAN Result = FALSE ;
2016-05-26 16:35:45 +00:00
ULONG i ;
LONGLONG LastVbn = 0 , LastLbn = 0 , Count = 0 ; // the last values we've found during traversal
2013-06-26 12:24:55 +00:00
2016-04-03 20:17:09 +00:00
DPRINT ( " FsRtlLookupBaseMcbEntry(%p, %I64d, %p, %p, %p, %p, %p) \n " , OpaqueMcb , Vbn , Lbn , SectorCountFromLbn , StartingLbn , SectorCountFromStartingLbn , Index ) ;
2016-05-26 16:35:45 +00:00
for ( i = 0 ; FsRtlGetNextBaseMcbEntry ( OpaqueMcb , i , & LastVbn , & LastLbn , & Count ) ; i + + )
2013-04-29 10:28:58 +00:00
{
2016-05-26 16:35:45 +00:00
// have we reached the target mapping?
if ( Vbn < LastVbn + Count )
2013-04-29 10:28:58 +00:00
{
2016-05-26 16:35:45 +00:00
if ( Lbn )
2013-06-26 12:24:55 +00:00
{
2016-05-26 16:35:45 +00:00
if ( LastLbn = = - 1 )
* Lbn = - 1 ;
else
* Lbn = LastLbn + ( Vbn - LastVbn ) ;
2013-06-26 12:24:55 +00:00
}
2016-05-26 16:35:45 +00:00
if ( SectorCountFromLbn )
* SectorCountFromLbn = LastVbn + Count - Vbn ;
if ( StartingLbn )
* StartingLbn = LastLbn ;
if ( SectorCountFromStartingLbn )
* SectorCountFromStartingLbn = LastVbn + Count - LastVbn ;
if ( Index )
* Index = i ;
2013-06-26 12:24:55 +00:00
2016-05-26 16:35:45 +00:00
Result = TRUE ;
goto quit ;
2013-06-26 12:24:55 +00:00
}
}
2016-04-03 20:17:09 +00:00
quit :
DPRINT ( " FsRtlLookupBaseMcbEntry(%p, %I64d, %p, %p, %p, %p, %p) = %d (%I64d, %I64d, %I64d, %I64d, %d) \n " ,
OpaqueMcb , Vbn , Lbn , SectorCountFromLbn , StartingLbn , SectorCountFromStartingLbn , Index , Result ,
( Lbn ? * Lbn : ( ULONGLONG ) - 1 ) , ( SectorCountFromLbn ? * SectorCountFromLbn : ( ULONGLONG ) - 1 ) , ( StartingLbn ? * StartingLbn : ( ULONGLONG ) - 1 ) ,
( SectorCountFromStartingLbn ? * SectorCountFromStartingLbn : ( ULONGLONG ) - 1 ) , ( Index ? * Index : ( ULONG ) - 1 ) ) ;
return Result ;
2012-02-29 09:18:01 +00:00
}
/*
* @ implemented
*/
BOOLEAN
NTAPI
2009-10-12 03:35:35 +00:00
FsRtlLookupLargeMcbEntry ( IN PLARGE_MCB Mcb ,
IN LONGLONG Vbn ,
OUT PLONGLONG Lbn OPTIONAL ,
OUT PLONGLONG SectorCountFromLbn OPTIONAL ,
OUT PLONGLONG StartingLbn OPTIONAL ,
OUT PLONGLONG SectorCountFromStartingLbn OPTIONAL ,
OUT PULONG Index OPTIONAL )
{
2012-02-29 09:18:01 +00:00
BOOLEAN Result ;
2016-04-03 20:17:09 +00:00
DPRINT ( " FsRtlLookupLargeMcbEntry(%p, %I64d, %p, %p, %p, %p, %p) \n " , Mcb , Vbn , Lbn , SectorCountFromLbn , StartingLbn , SectorCountFromStartingLbn , Index ) ;
2012-02-29 09:18:01 +00:00
KeAcquireGuardedMutex ( Mcb - > GuardedMutex ) ;
Result = FsRtlLookupBaseMcbEntry ( & ( Mcb - > BaseMcb ) ,
Vbn ,
Lbn ,
SectorCountFromLbn ,
StartingLbn ,
SectorCountFromStartingLbn ,
Index ) ;
KeReleaseGuardedMutex ( Mcb - > GuardedMutex ) ;
2016-04-03 20:17:09 +00:00
DPRINT ( " FsRtlLookupLargeMcbEntry(%p, %I64d, %p, %p, %p, %p, %p) = %d (%I64d, %I64d, %I64d, %I64d, %d) \n " ,
Mcb , Vbn , Lbn , SectorCountFromLbn , StartingLbn , SectorCountFromStartingLbn , Index , Result ,
( Lbn ? * Lbn : ( ULONGLONG ) - 1 ) , ( SectorCountFromLbn ? * SectorCountFromLbn : ( ULONGLONG ) - 1 ) , ( StartingLbn ? * StartingLbn : ( ULONGLONG ) - 1 ) ,
( SectorCountFromStartingLbn ? * SectorCountFromStartingLbn : ( ULONGLONG ) - 1 ) , ( Index ? * Index : ( ULONG ) - 1 ) ) ;
2012-02-29 09:18:01 +00:00
return Result ;
2009-10-12 03:35:35 +00:00
}
2013-06-26 12:24:55 +00:00
static BOOLEAN
NTAPI
FsRtlLookupLastLargeMcbEntryAndIndex_internal ( IN PBASE_MCB_INTERNAL Mcb ,
OUT PLONGLONG Vbn ,
OUT PLONGLONG Lbn ,
OUT PULONG Index OPTIONAL )
{
2014-11-13 20:11:05 +00:00
ULONG RunIndex = 0 ;
PLARGE_MCB_MAPPING_ENTRY Run , RunFound = NULL ;
LONGLONG LastVbn = 0 ;
2013-06-26 12:24:55 +00:00
2014-11-13 20:11:05 +00:00
for ( Run = ( PLARGE_MCB_MAPPING_ENTRY ) RtlEnumerateGenericTable ( & Mcb - > Mapping - > Table , TRUE ) ;
Run ;
Run = ( PLARGE_MCB_MAPPING_ENTRY ) RtlEnumerateGenericTable ( & Mcb - > Mapping - > Table , FALSE ) )
2013-06-26 12:24:55 +00:00
{
2014-11-13 20:11:05 +00:00
/* Take care when we must emulate missing 'hole' runs. */
if ( Run - > RunStartVbn . QuadPart > LastVbn )
{
RunIndex + + ;
}
LastVbn = Run - > RunEndVbn . QuadPart ;
RunIndex + + ;
RunFound = Run ;
}
2013-06-26 12:24:55 +00:00
2014-11-13 20:11:05 +00:00
if ( ! RunFound )
{
2013-06-26 12:24:55 +00:00
return FALSE ;
}
2014-11-13 20:11:05 +00:00
if ( Vbn )
{
* Vbn = RunFound - > RunEndVbn . QuadPart - 1 ;
}
if ( Lbn )
{
if ( 1 )
{
* Lbn = RunFound - > StartingLbn . QuadPart + ( RunFound - > RunEndVbn . QuadPart - RunFound - > RunStartVbn . QuadPart ) - 1 ;
}
else
{
* Lbn = ~ 0ULL ;
}
}
2013-06-26 12:24:55 +00:00
if ( Index )
{
2014-11-13 20:11:05 +00:00
* Index = RunIndex - 1 ;
2013-06-26 12:24:55 +00:00
}
return TRUE ;
}
2009-10-12 03:35:35 +00:00
/*
2013-06-26 12:24:55 +00:00
* @ implemented
2009-10-12 03:35:35 +00:00
*/
BOOLEAN
NTAPI
2012-02-29 09:18:01 +00:00
FsRtlLookupLastBaseMcbEntryAndIndex ( IN PBASE_MCB OpaqueMcb ,
IN OUT PLONGLONG LargeVbn ,
IN OUT PLONGLONG LargeLbn ,
IN OUT PULONG Index )
{
2016-04-03 20:17:09 +00:00
BOOLEAN Result ;
2013-04-29 10:10:44 +00:00
PBASE_MCB_INTERNAL Mcb = ( PBASE_MCB_INTERNAL ) OpaqueMcb ;
2012-02-29 09:18:01 +00:00
2016-04-03 20:17:09 +00:00
DPRINT ( " FsRtlLookupLastBaseMcbEntryAndIndex(%p, %p, %p, %p) \n " , OpaqueMcb , LargeVbn , LargeLbn , Index ) ;
Result = FsRtlLookupLastLargeMcbEntryAndIndex_internal ( Mcb , LargeVbn , LargeLbn , Index ) ;
DPRINT ( " FsRtlLookupLastBaseMcbEntryAndIndex(%p, %p, %p, %p) = %d (%I64d, %I64d, %d) \n " , OpaqueMcb , LargeVbn , LargeLbn , Index , Result , * LargeVbn , * LargeLbn , * Index ) ;
return Result ;
2012-02-29 09:18:01 +00:00
}
/*
* @ implemented
*/
BOOLEAN
NTAPI
2009-10-12 03:35:35 +00:00
FsRtlLookupLastLargeMcbEntryAndIndex ( IN PLARGE_MCB OpaqueMcb ,
OUT PLONGLONG LargeVbn ,
OUT PLONGLONG LargeLbn ,
OUT PULONG Index )
{
2012-02-29 09:18:01 +00:00
BOOLEAN Result ;
2016-04-03 20:17:09 +00:00
DPRINT ( " FsRtlLookupLastLargeMcbEntryAndIndex(%p, %p, %p, %p) \n " , OpaqueMcb , LargeVbn , LargeLbn , Index ) ;
2012-02-29 09:18:01 +00:00
KeAcquireGuardedMutex ( OpaqueMcb - > GuardedMutex ) ;
Result = FsRtlLookupLastBaseMcbEntryAndIndex ( & ( OpaqueMcb - > BaseMcb ) ,
LargeVbn ,
LargeLbn ,
Index ) ;
KeReleaseGuardedMutex ( OpaqueMcb - > GuardedMutex ) ;
2016-04-03 20:17:09 +00:00
DPRINT ( " FsRtlLookupLastLargeMcbEntryAndIndex(%p, %p, %p, %p) = %d (%I64d, %I64d, %d) \n " , OpaqueMcb , LargeVbn , LargeLbn , Index , Result , * LargeVbn , * LargeLbn , * Index ) ;
2012-02-29 09:18:01 +00:00
return Result ;
2009-10-12 03:35:35 +00:00
}
/*
* @ unimplemented
*/
BOOLEAN
NTAPI
2013-04-29 10:10:44 +00:00
FsRtlLookupLastBaseMcbEntry ( IN PBASE_MCB OpaqueMcb ,
2012-02-29 09:18:01 +00:00
OUT PLONGLONG Vbn ,
OUT PLONGLONG Lbn )
2009-10-12 03:35:35 +00:00
{
2016-04-03 20:17:09 +00:00
BOOLEAN Result ;
2013-04-29 10:10:44 +00:00
PBASE_MCB_INTERNAL Mcb = ( PBASE_MCB_INTERNAL ) OpaqueMcb ;
2013-04-29 10:28:58 +00:00
2016-04-03 20:17:09 +00:00
DPRINT ( " FsRtlLookupLastBaseMcbEntry(%p, %p, %p) \n " , OpaqueMcb , Vbn , Lbn ) ;
Result = FsRtlLookupLastLargeMcbEntryAndIndex_internal ( Mcb , Vbn , Lbn , NULL ) ; /* Index */
DPRINT ( " FsRtlLookupLastBaseMcbEntry(%p, %p, %p) = %d (%I64d, %I64d) \n " , Mcb , Vbn , Lbn , Result , * Vbn , * Lbn ) ;
return Result ;
2009-10-12 03:35:35 +00:00
}
/*
* @ implemented
*/
BOOLEAN
NTAPI
2012-02-29 09:18:01 +00:00
FsRtlLookupLastLargeMcbEntry ( IN PLARGE_MCB Mcb ,
OUT PLONGLONG Vbn ,
OUT PLONGLONG Lbn )
2009-10-12 03:35:35 +00:00
{
2012-02-29 09:18:01 +00:00
BOOLEAN Result ;
2016-04-03 20:17:09 +00:00
DPRINT ( " FsRtlLookupLastLargeMcbEntry(%p, %p, %p) \n " , Mcb , Vbn , Lbn ) ;
2012-02-29 09:18:01 +00:00
KeAcquireGuardedMutex ( Mcb - > GuardedMutex ) ;
Result = FsRtlLookupLastBaseMcbEntry ( & ( Mcb - > BaseMcb ) ,
Vbn ,
Lbn ) ;
KeReleaseGuardedMutex ( Mcb - > GuardedMutex ) ;
2016-04-03 20:17:09 +00:00
DPRINT ( " FsRtlLookupLastLargeMcbEntry(%p, %p, %p) = %d (%I64d, %I64d) \n " , Mcb , Vbn , Lbn , Result , * Vbn , * Lbn ) ;
2012-02-29 09:18:01 +00:00
return Result ;
2009-10-12 03:35:35 +00:00
}
/*
* @ implemented
*/
2012-02-29 09:18:01 +00:00
ULONG
2009-10-12 03:35:35 +00:00
NTAPI
2013-06-26 12:24:55 +00:00
FsRtlNumberOfRunsInBaseMcb ( IN PBASE_MCB OpaqueMcb )
2009-10-12 03:35:35 +00:00
{
2016-04-03 20:17:09 +00:00
ULONG NumberOfRuns = 0 ;
2016-05-26 16:35:45 +00:00
LONGLONG Vbn , Lbn , Count ;
int i ;
2016-04-03 20:17:09 +00:00
DPRINT ( " FsRtlNumberOfRunsInBaseMcb(%p) \n " , OpaqueMcb ) ;
2013-06-26 12:24:55 +00:00
2016-05-26 16:35:45 +00:00
// Count how many Mcb entries there are
for ( i = 0 ; FsRtlGetNextBaseMcbEntry ( OpaqueMcb , i , & Vbn , & Lbn , & Count ) ; i + + )
{
NumberOfRuns + + ;
}
2016-04-03 20:17:09 +00:00
DPRINT ( " FsRtlNumberOfRunsInBaseMcb(%p) = %d \n " , OpaqueMcb , NumberOfRuns ) ;
return NumberOfRuns ;
2009-10-12 03:35:35 +00:00
}
/*
* @ implemented
*/
ULONG
NTAPI
FsRtlNumberOfRunsInLargeMcb ( IN PLARGE_MCB Mcb )
{
ULONG NumberOfRuns ;
2016-04-03 20:17:09 +00:00
DPRINT ( " FsRtlNumberOfRunsInLargeMcb(%p) \n " , Mcb ) ;
2012-02-29 09:18:01 +00:00
2009-10-12 03:35:35 +00:00
/* Read the number of runs while holding the MCB lock */
KeAcquireGuardedMutex ( Mcb - > GuardedMutex ) ;
2013-06-26 12:24:55 +00:00
NumberOfRuns = FsRtlNumberOfRunsInBaseMcb ( & ( Mcb - > BaseMcb ) ) ;
2009-10-12 03:35:35 +00:00
KeReleaseGuardedMutex ( Mcb - > GuardedMutex ) ;
2016-04-03 20:17:09 +00:00
DPRINT ( " FsRtlNumberOfRunsInLargeMcb(%p) = %d \n " , Mcb , NumberOfRuns ) ;
2012-02-29 09:18:01 +00:00
2009-10-12 03:35:35 +00:00
/* Return the count */
return NumberOfRuns ;
}
/*
2013-06-26 12:24:55 +00:00
* @ implemented
* @ Mcb : # PLARGE_MCB initialized by FsRtlInitializeLargeMcb ( ) .
* % NULL value is forbidden .
* @ Vbn : Starting virtual block number to specify the range to delete .
* @ SectorCount : Length of the range to delete .
* Value less or equal to % 0 is forbidden ; FIXME : Is the reject of % 0 W32 compliant ?
*
* Deletes any possible @ Mcb mappings in the given range @ Vbn . . . @ Vbn + @ SectorCount - 1.
* This call has no problems if no mappings exist there yet .
2009-10-12 03:35:35 +00:00
*/
2012-02-29 09:18:01 +00:00
BOOLEAN
2009-10-12 03:35:35 +00:00
NTAPI
2013-04-29 10:10:44 +00:00
FsRtlRemoveBaseMcbEntry ( IN PBASE_MCB OpaqueMcb ,
2012-02-29 09:18:01 +00:00
IN LONGLONG Vbn ,
IN LONGLONG SectorCount )
2009-10-12 03:35:35 +00:00
{
2013-04-29 10:10:44 +00:00
PBASE_MCB_INTERNAL Mcb = ( PBASE_MCB_INTERNAL ) OpaqueMcb ;
2013-06-26 12:24:55 +00:00
LARGE_MCB_MAPPING_ENTRY NeedleRun ;
PLARGE_MCB_MAPPING_ENTRY HaystackRun ;
2016-04-03 20:17:09 +00:00
BOOLEAN Result = TRUE ;
DPRINT ( " FsRtlRemoveBaseMcbEntry(%p, %I64d, %I64d) \n " , OpaqueMcb , Vbn , SectorCount ) ;
if ( Vbn < 0 | | SectorCount < = 0 )
{
Result = FALSE ;
goto quit ;
}
2012-02-29 09:18:01 +00:00
2016-04-03 20:17:09 +00:00
if ( Vbn + SectorCount < = Vbn )
{
Result = FALSE ;
goto quit ;
}
2012-02-29 09:18:01 +00:00
2013-06-26 12:24:55 +00:00
NeedleRun . RunStartVbn . QuadPart = Vbn ;
NeedleRun . RunEndVbn . QuadPart = Vbn + SectorCount ;
2020-11-30 11:42:33 +00:00
NeedleRun . StartingLbn . QuadPart = - 1 ;
2013-06-26 12:24:55 +00:00
/* adjust/destroy all intersecting ranges */
Mcb - > Mapping - > Table . CompareRoutine = McbMappingIntersectCompare ;
while ( ( HaystackRun = RtlLookupElementGenericTable ( & Mcb - > Mapping - > Table , & NeedleRun ) ) )
2013-04-29 10:28:58 +00:00
{
2013-06-26 12:24:55 +00:00
if ( HaystackRun - > RunStartVbn . QuadPart < NeedleRun . RunStartVbn . QuadPart )
2013-04-29 10:28:58 +00:00
{
2020-11-30 11:42:33 +00:00
LONGLONG HaystackRunEnd = HaystackRun - > RunEndVbn . QuadPart ;
2013-06-26 12:24:55 +00:00
ASSERT ( HaystackRun - > RunEndVbn . QuadPart > NeedleRun . RunStartVbn . QuadPart ) ;
2020-11-30 11:42:33 +00:00
2013-06-26 12:24:55 +00:00
HaystackRun - > RunEndVbn . QuadPart = NeedleRun . RunStartVbn . QuadPart ;
2020-11-30 11:42:33 +00:00
if ( HaystackRunEnd > NeedleRun . RunEndVbn . QuadPart )
{
/* The run we are deleting is included in the run we just truncated.
* Add the tail back . */
LARGE_MCB_MAPPING_ENTRY TailRun ;
BOOLEAN NewElement ;
TailRun . RunStartVbn . QuadPart = NeedleRun . RunEndVbn . QuadPart ;
TailRun . RunEndVbn . QuadPart = HaystackRunEnd ;
TailRun . StartingLbn . QuadPart = HaystackRun - > StartingLbn . QuadPart + ( NeedleRun . RunEndVbn . QuadPart - HaystackRun - > RunStartVbn . QuadPart ) ;
Mcb - > Mapping - > Table . CompareRoutine = McbMappingCompare ;
RtlInsertElementGenericTable ( & Mcb - > Mapping - > Table , & TailRun , sizeof ( TailRun ) , & NewElement ) ;
+ + Mcb - > PairCount ;
ASSERT ( NewElement ) ;
Mcb - > Mapping - > Table . CompareRoutine = McbMappingIntersectCompare ;
}
2013-04-29 10:28:58 +00:00
}
2013-06-26 12:24:55 +00:00
else if ( HaystackRun - > RunEndVbn . QuadPart > NeedleRun . RunEndVbn . QuadPart )
2013-04-29 10:28:58 +00:00
{
2020-11-30 11:42:33 +00:00
LONGLONG HaystackRunStart = HaystackRun - > RunStartVbn . QuadPart ;
LONGLONG HaystackStartingLbn = HaystackRun - > StartingLbn . QuadPart ;
2013-06-26 12:24:55 +00:00
ASSERT ( HaystackRun - > RunStartVbn . QuadPart < NeedleRun . RunEndVbn . QuadPart ) ;
HaystackRun - > RunStartVbn . QuadPart = NeedleRun . RunEndVbn . QuadPart ;
2020-11-30 11:42:33 +00:00
/* Adjust the starting LBN */
HaystackRun - > StartingLbn . QuadPart + = NeedleRun . RunEndVbn . QuadPart - HaystackRunStart ;
if ( HaystackRunStart < NeedleRun . RunStartVbn . QuadPart )
{
/* The run we are deleting is included in the run we just truncated.
* Add the head back . */
LARGE_MCB_MAPPING_ENTRY HeadRun ;
BOOLEAN NewElement ;
HeadRun . RunStartVbn . QuadPart = HaystackRunStart ;
HeadRun . RunEndVbn . QuadPart = NeedleRun . RunStartVbn . QuadPart ;
HeadRun . StartingLbn . QuadPart = HaystackStartingLbn ;
Mcb - > Mapping - > Table . CompareRoutine = McbMappingCompare ;
RtlInsertElementGenericTable ( & Mcb - > Mapping - > Table , & HeadRun , sizeof ( HeadRun ) , & NewElement ) ;
+ + Mcb - > PairCount ;
ASSERT ( NewElement ) ;
Mcb - > Mapping - > Table . CompareRoutine = McbMappingIntersectCompare ;
}
2013-04-29 10:28:58 +00:00
}
else
{
2015-10-31 13:50:23 +00:00
//ASSERT(NeedleRun.RunStartVbn.QuadPart >= HaystackRun->RunStartVbn.QuadPart);
2014-11-13 20:11:05 +00:00
//ASSERT(NeedleRun.RunEndVbn.QuadPart <= HaystackRun->RunEndVbn.QuadPart);
2013-06-26 12:24:55 +00:00
Mcb - > Mapping - > Table . CompareRoutine = McbMappingCompare ;
RtlDeleteElementGenericTable ( & Mcb - > Mapping - > Table , HaystackRun ) ;
2016-04-18 20:49:14 +00:00
- - Mcb - > PairCount ;
2013-06-26 12:24:55 +00:00
Mcb - > Mapping - > Table . CompareRoutine = McbMappingIntersectCompare ;
2013-04-29 10:28:58 +00:00
}
}
2013-06-26 12:24:55 +00:00
Mcb - > Mapping - > Table . CompareRoutine = McbMappingCompare ;
2012-02-29 09:18:01 +00:00
2016-04-03 20:17:09 +00:00
quit :
DPRINT ( " FsRtlRemoveBaseMcbEntry(%p, %I64d, %I64d) = %d \n " , OpaqueMcb , Vbn , SectorCount , Result ) ;
return Result ;
2009-10-12 03:35:35 +00:00
}
/*
2012-02-29 09:18:01 +00:00
* @ implemented
2009-10-12 03:35:35 +00:00
*/
VOID
NTAPI
FsRtlRemoveLargeMcbEntry ( IN PLARGE_MCB Mcb ,
IN LONGLONG Vbn ,
IN LONGLONG SectorCount )
{
2016-04-03 20:17:09 +00:00
DPRINT ( " FsRtlRemoveLargeMcbEntry(%p, %I64d, %I64d) \n " , Mcb , Vbn , SectorCount ) ;
2012-02-29 09:18:01 +00:00
KeAcquireGuardedMutex ( Mcb - > GuardedMutex ) ;
2013-04-29 10:28:58 +00:00
FsRtlRemoveBaseMcbEntry ( & ( Mcb - > BaseMcb ) , Vbn , SectorCount ) ;
2012-02-29 09:18:01 +00:00
KeReleaseGuardedMutex ( Mcb - > GuardedMutex ) ;
2009-10-12 03:35:35 +00:00
}
/*
* @ implemented
*/
VOID
NTAPI
2013-04-29 10:10:44 +00:00
FsRtlResetBaseMcb ( IN PBASE_MCB OpaqueMcb )
2009-10-12 03:35:35 +00:00
{
2013-04-29 10:10:44 +00:00
PBASE_MCB_INTERNAL Mcb = ( PBASE_MCB_INTERNAL ) OpaqueMcb ;
2013-04-29 10:28:58 +00:00
PLARGE_MCB_MAPPING_ENTRY Element ;
2012-02-29 09:18:01 +00:00
2016-04-03 20:17:09 +00:00
DPRINT ( " FsRtlResetBaseMcb(%p) \n " , OpaqueMcb ) ;
2013-04-29 10:28:58 +00:00
while ( RtlNumberGenericTableElements ( & Mcb - > Mapping - > Table ) & &
( Element = ( PLARGE_MCB_MAPPING_ENTRY ) RtlGetElementGenericTable ( & Mcb - > Mapping - > Table , 0 ) ) )
{
RtlDeleteElementGenericTable ( & Mcb - > Mapping - > Table , Element ) ;
}
2012-02-29 09:18:01 +00:00
2013-04-29 10:28:58 +00:00
Mcb - > PairCount = 0 ;
Mcb - > MaximumPairCount = 0 ;
2009-10-12 03:35:35 +00:00
}
/*
2012-02-29 09:18:01 +00:00
* @ implemented
2009-10-12 03:35:35 +00:00
*/
VOID
NTAPI
FsRtlResetLargeMcb ( IN PLARGE_MCB Mcb ,
IN BOOLEAN SelfSynchronized )
{
2016-04-03 20:17:09 +00:00
DPRINT ( " FsRtlResetLargeMcb(%p, %d) \n " , Mcb , SelfSynchronized ) ;
2012-02-29 09:18:01 +00:00
if ( ! SelfSynchronized )
KeAcquireGuardedMutex ( Mcb - > GuardedMutex ) ;
2013-04-29 10:28:58 +00:00
FsRtlResetBaseMcb ( & Mcb - > BaseMcb ) ;
2012-02-29 09:18:01 +00:00
if ( ! SelfSynchronized )
2013-04-29 10:28:58 +00:00
KeReleaseGuardedMutex ( Mcb - > GuardedMutex ) ;
2012-02-29 09:18:01 +00:00
}
2009-10-12 03:35:35 +00:00
/*
* @ unimplemented
*/
BOOLEAN
NTAPI
2013-04-29 10:10:44 +00:00
FsRtlSplitBaseMcb ( IN PBASE_MCB OpaqueMcb ,
2012-02-29 09:18:01 +00:00
IN LONGLONG Vbn ,
IN LONGLONG Amount )
{
2013-06-27 09:18:32 +00:00
PBASE_MCB_INTERNAL Mcb = ( PBASE_MCB_INTERNAL ) OpaqueMcb ;
PLARGE_MCB_MAPPING_ENTRY Run , InsertLowerRun = NULL , ExistingRun = NULL ;
BOOLEAN NewElement ;
2016-04-03 20:17:09 +00:00
DPRINT ( " FsRtlSplitBaseMcb(%p, %I64d, %I64d) \n " , OpaqueMcb , Vbn , Amount ) ;
2013-06-27 09:18:32 +00:00
/* Traverse the tree */
for ( Run = ( PLARGE_MCB_MAPPING_ENTRY ) RtlEnumerateGenericTable ( & Mcb - > Mapping - > Table , TRUE ) ;
Run ;
Run = ( PLARGE_MCB_MAPPING_ENTRY ) RtlEnumerateGenericTable ( & Mcb - > Mapping - > Table , FALSE ) )
{
/* unaffected run? */
/* FIXME: performance: effective skip of all 'lower' runs without traversing them */
2014-11-13 20:11:05 +00:00
if ( Vbn > = Run - > RunEndVbn . QuadPart ) { DPRINT ( " Skipping it \n " ) ; continue ; }
2013-06-27 09:18:32 +00:00
/* crossing run to be split?
* ' lower_run ' is created on the original place ; just shortened .
* current ' run ' is shifted up later
*/
if ( Vbn < Run - > RunEndVbn . QuadPart )
{
/* FIXME: shift 'run->Lbn_start' ? */
Run - > RunStartVbn . QuadPart = Vbn ;
2014-11-13 20:11:05 +00:00
InsertLowerRun = NULL ;
2013-06-27 09:18:32 +00:00
}
2013-04-29 10:28:58 +00:00
2013-06-27 09:18:32 +00:00
/* Shift the current 'run'.
* Ordering is not changed in Generic Tree so I hope I do not need to reinsert it .
*/
Run - > RunStartVbn . QuadPart + = Amount ;
ASSERT ( Run - > RunEndVbn . QuadPart + Amount > Run - > RunEndVbn . QuadPart ) ; /* overflow? */
Run - > RunEndVbn . QuadPart + = Amount ;
/* FIXME: shift 'run->Lbn_start' ? */
2013-04-29 10:28:58 +00:00
2013-06-27 09:18:32 +00:00
/* continue the traversal */
}
if ( InsertLowerRun )
2016-04-18 20:49:14 +00:00
{
2013-06-27 09:18:32 +00:00
ExistingRun = RtlInsertElementGenericTable ( & Mcb - > Mapping - > Table , InsertLowerRun , sizeof ( * InsertLowerRun ) , & NewElement ) ;
2016-04-18 20:49:14 +00:00
+ + Mcb - > PairCount ;
}
2013-06-27 09:18:32 +00:00
ASSERT ( ExistingRun = = NULL ) ;
2016-04-03 20:17:09 +00:00
DPRINT ( " FsRtlSplitBaseMcb(%p, %I64d, %I64d) = %d \n " , OpaqueMcb , Vbn , Amount , TRUE ) ;
2014-11-13 20:11:05 +00:00
return TRUE ;
2012-02-29 09:18:01 +00:00
}
/*
* @ implemented
*/
BOOLEAN
NTAPI
2009-10-12 03:35:35 +00:00
FsRtlSplitLargeMcb ( IN PLARGE_MCB Mcb ,
IN LONGLONG Vbn ,
IN LONGLONG Amount )
{
2012-02-29 09:18:01 +00:00
BOOLEAN Result ;
2016-04-03 20:17:09 +00:00
DPRINT ( " FsRtlSplitLargeMcb(%p, %I64d, %I64d) \n " , Mcb , Vbn , Amount ) ;
2012-02-29 09:18:01 +00:00
KeAcquireGuardedMutex ( Mcb - > GuardedMutex ) ;
Result = FsRtlSplitBaseMcb ( & ( Mcb - > BaseMcb ) ,
Vbn ,
Amount ) ;
KeReleaseGuardedMutex ( Mcb - > GuardedMutex ) ;
2016-04-03 20:17:09 +00:00
DPRINT ( " FsRtlSplitLargeMcb(%p, %I64d, %I64d) = %d \n " , Mcb , Vbn , Amount , Result ) ;
2012-02-29 09:18:01 +00:00
return Result ;
2009-10-12 03:35:35 +00:00
}
/*
* @ unimplemented
*/
VOID
NTAPI
2013-04-29 10:10:44 +00:00
FsRtlTruncateBaseMcb ( IN PBASE_MCB OpaqueMcb ,
2012-02-29 09:18:01 +00:00
IN LONGLONG Vbn )
2009-10-12 03:35:35 +00:00
{
2016-04-03 20:17:09 +00:00
DPRINT ( " FsRtlTruncateBaseMcb(%p, %I64d) \n " , OpaqueMcb , Vbn ) ;
2014-11-13 20:11:05 +00:00
FsRtlRemoveBaseMcbEntry ( OpaqueMcb , Vbn , MAXLONG - Vbn + 1 ) ;
2009-10-12 03:35:35 +00:00
}
/*
* @ implemented
*/
VOID
NTAPI
2012-02-29 09:18:01 +00:00
FsRtlTruncateLargeMcb ( IN PLARGE_MCB Mcb ,
IN LONGLONG Vbn )
2011-02-23 12:04:08 +00:00
{
2016-04-03 20:17:09 +00:00
DPRINT ( " FsRtlTruncateLargeMcb(%p, %I64d) \n " , Mcb , Vbn ) ;
2012-02-29 09:18:01 +00:00
KeAcquireGuardedMutex ( Mcb - > GuardedMutex ) ;
2013-04-29 10:28:58 +00:00
FsRtlTruncateBaseMcb ( & ( Mcb - > BaseMcb ) , Vbn ) ;
2012-02-29 09:18:01 +00:00
KeReleaseGuardedMutex ( Mcb - > GuardedMutex ) ;
2011-02-23 12:04:08 +00:00
}
/*
2012-02-29 09:18:01 +00:00
* @ implemented
2011-02-23 12:04:08 +00:00
*/
VOID
NTAPI
2012-02-29 09:18:01 +00:00
FsRtlUninitializeBaseMcb ( IN PBASE_MCB Mcb )
2011-02-23 12:04:08 +00:00
{
2016-04-03 20:17:09 +00:00
DPRINT ( " FsRtlUninitializeBaseMcb(%p) \n " , Mcb ) ;
2013-04-29 10:28:58 +00:00
FsRtlResetBaseMcb ( Mcb ) ;
2012-02-29 09:18:01 +00:00
2013-06-26 12:24:55 +00:00
if ( ( Mcb - > PoolType = = PagedPool ) /* && (Mcb->MaximumPairCount == MAXIMUM_PAIR_COUNT)*/ )
2012-02-29 09:18:01 +00:00
{
ExFreeToPagedLookasideList ( & FsRtlFirstMappingLookasideList ,
Mcb - > Mapping ) ;
}
else
{
2019-11-01 18:05:20 +00:00
ExFreePoolWithTag ( Mcb - > Mapping , ' CBSF ' ) ;
2012-02-29 09:18:01 +00:00
}
2009-10-12 03:35:35 +00:00
}
/*
* @ implemented
*/
VOID
NTAPI
2012-02-29 09:18:01 +00:00
FsRtlUninitializeLargeMcb ( IN PLARGE_MCB Mcb )
2009-10-12 03:35:35 +00:00
{
2016-04-03 20:17:09 +00:00
DPRINT ( " FsRtlUninitializeLargeMcb(%p) \n " , Mcb ) ;
2012-02-29 09:18:01 +00:00
if ( Mcb - > GuardedMutex )
{
ExFreeToNPagedLookasideList ( & FsRtlFastMutexLookasideList ,
Mcb - > GuardedMutex ) ;
FsRtlUninitializeBaseMcb ( & ( Mcb - > BaseMcb ) ) ;
}
2009-10-12 03:35:35 +00:00
}