ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

largemcb.c
Go to the documentation of this file.
00001 /*
00002  * PROJECT:         ReactOS Kernel
00003  * LICENSE:         GPL - See COPYING in the top level directory
00004  * FILE:            ntoskrnl/fsrtl/largemcb.c
00005  * PURPOSE:         Large Mapped Control Block (MCB) support for File System Drivers
00006  * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)
00007  *                  Pierre Schweitzer (heis_spiter@hotmail.com) 
00008  *                  Art Yerkes (art.yerkes@gmail.com)
00009  */
00010 
00011 /* INCLUDES ******************************************************************/
00012 
00013 #include <ntoskrnl.h>
00014 //#define NDEBUG
00015 #include <debug.h>
00016 
00017 /* GLOBALS *******************************************************************/
00018 
00019 #define GET_LIST_HEAD(x) ((PLIST_ENTRY)(&((PRTL_GENERIC_TABLE)x)[1]))
00020 
00021 PAGED_LOOKASIDE_LIST FsRtlFirstMappingLookasideList;
00022 NPAGED_LOOKASIDE_LIST FsRtlFastMutexLookasideList;
00023 
00024 typedef struct _LARGE_MCB_MAPPING_ENTRY
00025 {
00026     LARGE_INTEGER RunStartVbn;
00027     LARGE_INTEGER SectorCount;
00028     LARGE_INTEGER StartingLbn;
00029     LIST_ENTRY Sequence;
00030 } LARGE_MCB_MAPPING_ENTRY, *PLARGE_MCB_MAPPING_ENTRY;
00031 
00032 static PVOID NTAPI McbMappingAllocate(PRTL_GENERIC_TABLE Table, CLONG Bytes)
00033 {
00034     PVOID Result;
00035     PBASE_MCB Mcb = (PBASE_MCB)Table->TableContext;
00036     Result = ExAllocatePoolWithTag(Mcb->PoolType, Bytes, 'LMCB');
00037     DPRINT("McbMappingAllocate(%d) => %p\n", Bytes, Result);
00038     return Result;
00039 }
00040 
00041 static VOID NTAPI McbMappingFree(PRTL_GENERIC_TABLE Table, PVOID Buffer)
00042 {
00043     DPRINT("McbMappingFree(%p)\n", Buffer);
00044     ExFreePoolWithTag(Buffer, 'LMCB');
00045 }
00046 
00047 static RTL_GENERIC_COMPARE_RESULTS NTAPI McbMappingCompare
00048 (RTL_GENERIC_TABLE Table, PVOID PtrA, PVOID PtrB)
00049 {
00050     PLARGE_MCB_MAPPING_ENTRY A = PtrA, B = PtrB;
00051     return 
00052         (A->RunStartVbn.QuadPart + A->SectorCount.QuadPart <
00053          B->RunStartVbn.QuadPart) ? GenericLessThan :
00054         (A->RunStartVbn.QuadPart > 
00055          B->RunStartVbn.QuadPart + B->SectorCount.QuadPart) ? 
00056         GenericGreaterThan : GenericEqual;
00057 }
00058 
00059 /* PUBLIC FUNCTIONS **********************************************************/
00060 
00061 /*
00062  * @implemented
00063  */
00064 BOOLEAN
00065 NTAPI
00066 FsRtlAddBaseMcbEntry(IN PBASE_MCB Mcb,
00067                      IN LONGLONG Vbn,
00068                      IN LONGLONG Lbn,
00069                      IN LONGLONG SectorCount)
00070 {
00071     LARGE_MCB_MAPPING_ENTRY Node;
00072     PLARGE_MCB_MAPPING_ENTRY Existing = NULL;
00073     BOOLEAN NewElement = FALSE;
00074 
00075     Node.RunStartVbn.QuadPart = Vbn;
00076     Node.StartingLbn.QuadPart = Lbn;
00077     Node.SectorCount.QuadPart = SectorCount;
00078 
00079     while (!NewElement)
00080     {
00081         DPRINT("Inserting %x:%x\n", Node.RunStartVbn.LowPart, Node.SectorCount.LowPart);
00082         Existing = RtlInsertElementGenericTable
00083             (Mcb->Mapping, &Node, sizeof(Node), &NewElement);
00084         DPRINT("Existing %x\n", Existing);
00085         if (!Existing) break;
00086 
00087         DPRINT("NewElement %d\n", NewElement);
00088         if (!NewElement)
00089         {
00090             // We merge the existing runs
00091             LARGE_INTEGER StartVbn, FinalVbn;
00092             DPRINT("Existing: %x:%x\n", 
00093                    Existing->RunStartVbn.LowPart, Node.SectorCount.LowPart);
00094             if (Existing->RunStartVbn.QuadPart < Node.RunStartVbn.QuadPart)
00095             {
00096                 StartVbn = Existing->RunStartVbn;
00097                 Node.StartingLbn = Existing->StartingLbn;
00098             }
00099             else
00100             {
00101                 StartVbn = Node.RunStartVbn;
00102             }
00103             DPRINT("StartVbn %x\n", StartVbn.LowPart);
00104             if (Existing->RunStartVbn.QuadPart + Existing->SectorCount.QuadPart >
00105                 Node.RunStartVbn.QuadPart + Node.SectorCount.QuadPart)
00106             {
00107                 FinalVbn.QuadPart = 
00108                     Existing->RunStartVbn.QuadPart + Existing->SectorCount.QuadPart;
00109             }
00110             else
00111             {
00112                 FinalVbn.QuadPart =
00113                     Node.RunStartVbn.QuadPart + Node.SectorCount.QuadPart;
00114             }
00115             DPRINT("FinalVbn %x\n", FinalVbn.LowPart);
00116             Node.RunStartVbn.QuadPart = StartVbn.QuadPart;
00117             Node.SectorCount.QuadPart = FinalVbn.QuadPart - StartVbn.QuadPart;
00118             RemoveHeadList(&Existing->Sequence);
00119             RtlDeleteElementGenericTable(Mcb->Mapping, Existing);
00120             Mcb->PairCount--;
00121         }
00122         else
00123         {
00124             DPRINT("Mapping added %x\n", Existing);
00125             Mcb->MaximumPairCount++;
00126             Mcb->PairCount++;
00127             InsertHeadList(GET_LIST_HEAD(Mcb->Mapping), &Existing->Sequence);
00128         }
00129     }
00130 
00131     DPRINT("!!Existing %d\n", !!Existing);
00132     return !!Existing;
00133 }
00134 
00135 /*
00136  * @implemented
00137  */
00138 BOOLEAN
00139 NTAPI
00140 FsRtlAddLargeMcbEntry(IN PLARGE_MCB Mcb,
00141                       IN LONGLONG Vbn,
00142                       IN LONGLONG Lbn,
00143                       IN LONGLONG SectorCount)
00144 {
00145     BOOLEAN Result;
00146 
00147     DPRINT("Mcb %x Vbn %x Lbn %x SectorCount %x\n", Mcb, Vbn, Lbn, SectorCount);
00148 
00149     KeAcquireGuardedMutex(Mcb->GuardedMutex);
00150     Result = FsRtlAddBaseMcbEntry(&(Mcb->BaseMcb),
00151                                   Vbn,
00152                                   Lbn,
00153                                   SectorCount);
00154     KeReleaseGuardedMutex(Mcb->GuardedMutex);
00155 
00156     DPRINT("Done %d\n", Result);
00157 
00158     return Result;
00159 }
00160 
00161 /*
00162  * @unimplemented
00163  */
00164 BOOLEAN
00165 NTAPI
00166 FsRtlGetNextBaseMcbEntry(IN PBASE_MCB Mcb,
00167                          IN ULONG RunIndex,
00168                          OUT PLONGLONG Vbn,
00169                          OUT PLONGLONG Lbn,
00170                          OUT PLONGLONG SectorCount)
00171 {
00172     ULONG i = 0;
00173     BOOLEAN Result = FALSE;
00174     PLARGE_MCB_MAPPING_ENTRY Entry;
00175     for (Entry = (PLARGE_MCB_MAPPING_ENTRY)
00176              RtlEnumerateGenericTable(Mcb->Mapping, TRUE);
00177          Entry && i < RunIndex;
00178          Entry = (PLARGE_MCB_MAPPING_ENTRY)
00179              RtlEnumerateGenericTable(Mcb->Mapping, FALSE), i++);
00180     if (Entry)
00181     {
00182         Result = TRUE;
00183         if (Vbn)
00184             *Vbn = Entry->RunStartVbn.QuadPart;
00185         if (Lbn)
00186             *Lbn = Entry->StartingLbn.QuadPart;
00187         if (SectorCount)
00188             *SectorCount = Entry->SectorCount.QuadPart;
00189     }
00190 
00191     return Result;
00192 }
00193 
00194 /*
00195  * @implemented
00196  */
00197 BOOLEAN
00198 NTAPI
00199 FsRtlGetNextLargeMcbEntry(IN PLARGE_MCB Mcb,
00200                           IN ULONG RunIndex,
00201                           OUT PLONGLONG Vbn,
00202                           OUT PLONGLONG Lbn,
00203                           OUT PLONGLONG SectorCount)
00204 {
00205     BOOLEAN Result;
00206 
00207     DPRINT("FsRtlGetNextLargeMcbEntry Mcb %x RunIndex %x\n", Mcb, RunIndex);
00208 
00209     KeAcquireGuardedMutex(Mcb->GuardedMutex);
00210     Result = FsRtlGetNextBaseMcbEntry(&(Mcb->BaseMcb),
00211                                       RunIndex,
00212                                       Vbn,
00213                                       Lbn,
00214                                       SectorCount);
00215     KeReleaseGuardedMutex(Mcb->GuardedMutex);
00216 
00217     DPRINT("Done %d\n", Result);
00218 
00219     return Result;
00220 }
00221 
00222 /*
00223  * @implemented
00224  */
00225 VOID
00226 NTAPI
00227 FsRtlInitializeBaseMcb(IN PBASE_MCB Mcb,
00228                        IN POOL_TYPE PoolType)
00229 {
00230     Mcb->PairCount = 0;
00231 
00232     if (PoolType == PagedPool)
00233     {
00234         Mcb->Mapping = ExAllocateFromPagedLookasideList(&FsRtlFirstMappingLookasideList);
00235     }
00236     else
00237     {
00238         Mcb->Mapping = ExAllocatePoolWithTag(PoolType | POOL_RAISE_IF_ALLOCATION_FAILURE,
00239                                              sizeof(RTL_GENERIC_TABLE) + sizeof(LIST_ENTRY),
00240                                              'FSBC');
00241     }
00242 
00243     Mcb->PoolType = PoolType;
00244     Mcb->MaximumPairCount = MAXIMUM_PAIR_COUNT;
00245     RtlInitializeGenericTable
00246         (Mcb->Mapping,
00247          (PRTL_GENERIC_COMPARE_ROUTINE)McbMappingCompare,
00248          McbMappingAllocate,
00249          McbMappingFree,
00250          Mcb);
00251     InitializeListHead(GET_LIST_HEAD(Mcb->Mapping));
00252 }
00253 
00254 /*
00255  * @implemented
00256  */
00257 VOID
00258 NTAPI
00259 FsRtlInitializeLargeMcb(IN PLARGE_MCB Mcb,
00260                         IN POOL_TYPE PoolType)
00261 {
00262     Mcb->GuardedMutex = ExAllocateFromNPagedLookasideList(&FsRtlFastMutexLookasideList);
00263 
00264     KeInitializeGuardedMutex(Mcb->GuardedMutex);
00265 
00266     _SEH2_TRY
00267     {
00268         FsRtlInitializeBaseMcb(&(Mcb->BaseMcb), PoolType);
00269     }
00270     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
00271     {
00272         ExFreeToNPagedLookasideList(&FsRtlFastMutexLookasideList,
00273                                     Mcb->GuardedMutex);
00274         Mcb->GuardedMutex = NULL;
00275     }
00276     _SEH2_END;
00277 }
00278 
00279 /*
00280  * @implemented
00281  */
00282 VOID
00283 NTAPI
00284 FsRtlInitializeLargeMcbs(VOID)
00285 {
00286     /* Initialize the list for the MCB */
00287     ExInitializePagedLookasideList(&FsRtlFirstMappingLookasideList,
00288                                    NULL,
00289                                    NULL,
00290                                    POOL_RAISE_IF_ALLOCATION_FAILURE,
00291                                    sizeof(RTL_GENERIC_TABLE) + sizeof(LIST_ENTRY),
00292                                    IFS_POOL_TAG,
00293                                    0); /* FIXME: Should be 4 */
00294 
00295     /* Initialize the list for the guarded mutex */
00296     ExInitializeNPagedLookasideList(&FsRtlFastMutexLookasideList,
00297                                     NULL,
00298                                     NULL,
00299                                     POOL_RAISE_IF_ALLOCATION_FAILURE,
00300                                     sizeof(KGUARDED_MUTEX),
00301                                     IFS_POOL_TAG,
00302                                     0); /* FIXME: Should be 32 */
00303 }
00304 
00305 /*
00306  * @unimplemented
00307  */
00308 BOOLEAN
00309 NTAPI
00310 FsRtlLookupBaseMcbEntry(IN PBASE_MCB Mcb,
00311                         IN LONGLONG Vbn,
00312                         OUT PLONGLONG Lbn OPTIONAL,
00313                         OUT PLONGLONG SectorCountFromLbn OPTIONAL,
00314                         OUT PLONGLONG StartingLbn OPTIONAL,
00315                         OUT PLONGLONG SectorCountFromStartingLbn OPTIONAL,
00316                         OUT PULONG Index OPTIONAL)
00317 {
00318     BOOLEAN Result = FALSE;
00319     LARGE_MCB_MAPPING_ENTRY ToLookup;
00320     PLARGE_MCB_MAPPING_ENTRY Entry;
00321 
00322     ToLookup.RunStartVbn.QuadPart = Vbn;
00323     ToLookup.SectorCount.QuadPart = 1;
00324 
00325     Entry = RtlLookupElementGenericTable(Mcb->Mapping, &ToLookup);
00326     if (!Entry)
00327     {
00328         // Find out if we have a following entry.  The spec says we should return
00329         // found with Lbn == -1 when we're beneath the largest map.
00330         ToLookup.SectorCount.QuadPart = (1ull<<62) - ToLookup.RunStartVbn.QuadPart;
00331         Entry = RtlLookupElementGenericTable(Mcb->Mapping, &ToLookup);
00332         if (Entry)
00333         {
00334             Result = TRUE;
00335             if (Lbn) *Lbn = ~0ull;
00336         }
00337         else
00338         {
00339             Result = FALSE;
00340         }
00341     }
00342     else
00343     {
00344         LARGE_INTEGER Offset;
00345         Offset.QuadPart = Vbn - Entry->RunStartVbn.QuadPart;
00346         Result = TRUE;
00347         if (Lbn) *Lbn = Entry->StartingLbn.QuadPart + Offset.QuadPart;
00348         if (SectorCountFromLbn) *SectorCountFromLbn = Entry->SectorCount.QuadPart - Offset.QuadPart;
00349         if (StartingLbn) *StartingLbn = Entry->StartingLbn.QuadPart;
00350         if (SectorCountFromStartingLbn) *SectorCountFromStartingLbn = Entry->SectorCount.QuadPart;
00351     }
00352     
00353     return Result;
00354 }
00355 
00356 /*
00357  * @implemented
00358  */
00359 BOOLEAN
00360 NTAPI
00361 FsRtlLookupLargeMcbEntry(IN PLARGE_MCB Mcb,
00362                          IN LONGLONG Vbn,
00363                          OUT PLONGLONG Lbn OPTIONAL,
00364                          OUT PLONGLONG SectorCountFromLbn OPTIONAL,
00365                          OUT PLONGLONG StartingLbn OPTIONAL,
00366                          OUT PLONGLONG SectorCountFromStartingLbn OPTIONAL,
00367                          OUT PULONG Index OPTIONAL)
00368 {
00369     BOOLEAN Result;
00370 
00371     DPRINT("FsRtlLookupLargeMcbEntry Mcb %x Vbn %x\n", Mcb, (ULONG)Vbn);
00372 
00373     KeAcquireGuardedMutex(Mcb->GuardedMutex);
00374     Result = FsRtlLookupBaseMcbEntry(&(Mcb->BaseMcb),
00375                                      Vbn,
00376                                      Lbn,
00377                                      SectorCountFromLbn,
00378                                      StartingLbn,
00379                                      SectorCountFromStartingLbn,
00380                                      Index);
00381     KeReleaseGuardedMutex(Mcb->GuardedMutex);
00382 
00383     DPRINT("Done %d\n", Result);
00384 
00385     return Result;
00386 }
00387 
00388 /*
00389  * @unimplemented
00390  */
00391 BOOLEAN
00392 NTAPI
00393 FsRtlLookupLastBaseMcbEntryAndIndex(IN PBASE_MCB OpaqueMcb,
00394                                     IN OUT PLONGLONG LargeVbn,
00395                                     IN OUT PLONGLONG LargeLbn,
00396                                     IN OUT PULONG Index)
00397 {
00398     ULONG i = 0;
00399     BOOLEAN Result = FALSE;
00400     PLIST_ENTRY ListEntry;
00401     PLARGE_MCB_MAPPING_ENTRY Entry;
00402     PLARGE_MCB_MAPPING_ENTRY CountEntry;
00403 
00404     ListEntry = GET_LIST_HEAD(OpaqueMcb->Mapping);
00405     if (!IsListEmpty(ListEntry))
00406     {
00407         Entry = CONTAINING_RECORD(ListEntry->Flink, LARGE_MCB_MAPPING_ENTRY, Sequence);
00408         Result = TRUE;
00409         *LargeVbn = Entry->RunStartVbn.QuadPart;
00410         *LargeLbn = Entry->StartingLbn.QuadPart;
00411 
00412         for (i = 0, CountEntry = RtlEnumerateGenericTable(OpaqueMcb->Mapping, TRUE);
00413              CountEntry != Entry;
00414              CountEntry = RtlEnumerateGenericTable(OpaqueMcb->Mapping, FALSE));
00415 
00416         *Index = i;
00417     }
00418 
00419     return Result;
00420 }
00421 
00422 /*
00423  * @implemented
00424  */
00425 BOOLEAN
00426 NTAPI
00427 FsRtlLookupLastLargeMcbEntryAndIndex(IN PLARGE_MCB OpaqueMcb,
00428                                      OUT PLONGLONG LargeVbn,
00429                                      OUT PLONGLONG LargeLbn,
00430                                      OUT PULONG Index)
00431 {
00432     BOOLEAN Result;
00433 
00434     DPRINT("FsRtlLookupLastLargeMcbEntryAndIndex %x\n", OpaqueMcb);
00435 
00436     KeAcquireGuardedMutex(OpaqueMcb->GuardedMutex);
00437     Result = FsRtlLookupLastBaseMcbEntryAndIndex(&(OpaqueMcb->BaseMcb),
00438                                                  LargeVbn,
00439                                                  LargeLbn,
00440                                                  Index);
00441     KeReleaseGuardedMutex(OpaqueMcb->GuardedMutex);
00442 
00443     DPRINT("Done %d\n", Result);
00444 
00445     return Result;
00446 }
00447 
00448 /*
00449  * @unimplemented
00450  */
00451 BOOLEAN
00452 NTAPI
00453 FsRtlLookupLastBaseMcbEntry(IN PBASE_MCB Mcb,
00454                             OUT PLONGLONG Vbn,
00455                             OUT PLONGLONG Lbn)
00456 {
00457     BOOLEAN Result = FALSE;
00458     PLIST_ENTRY ListEntry;
00459     PLARGE_MCB_MAPPING_ENTRY Entry;
00460 
00461     ListEntry = GET_LIST_HEAD(Mcb->Mapping);
00462     if (!IsListEmpty(ListEntry))
00463     {
00464         Entry = CONTAINING_RECORD(ListEntry->Flink, LARGE_MCB_MAPPING_ENTRY, Sequence);
00465         Result = TRUE;
00466         *Vbn = Entry->RunStartVbn.QuadPart;
00467         *Lbn = Entry->StartingLbn.QuadPart;
00468     }
00469     
00470     return Result;
00471 }
00472 
00473 /*
00474  * @implemented
00475  */
00476 BOOLEAN
00477 NTAPI
00478 FsRtlLookupLastLargeMcbEntry(IN PLARGE_MCB Mcb,
00479                              OUT PLONGLONG Vbn,
00480                              OUT PLONGLONG Lbn)
00481 {
00482     BOOLEAN Result;
00483 
00484     DPRINT("FsRtlLookupLastLargeMcbEntry Mcb %x\n", Mcb);
00485 
00486     KeAcquireGuardedMutex(Mcb->GuardedMutex);
00487     Result = FsRtlLookupLastBaseMcbEntry(&(Mcb->BaseMcb),
00488                                          Vbn,
00489                                          Lbn);
00490     KeReleaseGuardedMutex(Mcb->GuardedMutex);
00491 
00492     DPRINT("Done %d\n", Result);
00493 
00494     return Result;
00495 }
00496 
00497 /*
00498  * @implemented
00499  */
00500 ULONG
00501 NTAPI
00502 FsRtlNumberOfRunsInBaseMcb(IN PBASE_MCB Mcb)
00503 {
00504     /* Return the count */
00505     return Mcb->PairCount;
00506 }
00507 
00508 /*
00509  * @implemented
00510  */
00511 ULONG
00512 NTAPI
00513 FsRtlNumberOfRunsInLargeMcb(IN PLARGE_MCB Mcb)
00514 {
00515     ULONG NumberOfRuns;
00516 
00517     DPRINT("FsRtlNumberOfRunsInLargeMcb Mcb %x\n", Mcb);
00518 
00519     /* Read the number of runs while holding the MCB lock */
00520     KeAcquireGuardedMutex(Mcb->GuardedMutex);
00521     NumberOfRuns = Mcb->BaseMcb.PairCount;
00522     KeReleaseGuardedMutex(Mcb->GuardedMutex);
00523 
00524     DPRINT("Done %d\n", NumberOfRuns);
00525 
00526     /* Return the count */
00527     return NumberOfRuns;
00528 }
00529 
00530 /*
00531  * @unimplemented
00532  */
00533 BOOLEAN
00534 NTAPI
00535 FsRtlRemoveBaseMcbEntry(IN PBASE_MCB Mcb,
00536                         IN LONGLONG Vbn,
00537                         IN LONGLONG SectorCount)
00538 {
00539     LARGE_MCB_MAPPING_ENTRY Node;
00540     PLARGE_MCB_MAPPING_ENTRY Element;
00541 
00542     Node.RunStartVbn.QuadPart = Vbn;
00543     Node.SectorCount.QuadPart = SectorCount;
00544 
00545     while ((Element = RtlLookupElementGenericTable(Mcb->Mapping, &Node)))
00546     {
00547         // Must split
00548         if (Element->RunStartVbn.QuadPart < Node.RunStartVbn.QuadPart &&
00549             Element->SectorCount.QuadPart > Node.SectorCount.QuadPart)
00550         {
00551             LARGE_MCB_MAPPING_ENTRY Upper, Reinsert;
00552             PLARGE_MCB_MAPPING_ENTRY Reinserted, Inserted;
00553             LARGE_INTEGER StartHole = Node.RunStartVbn;
00554             LARGE_INTEGER EndHole;
00555             EndHole.QuadPart = Node.RunStartVbn.QuadPart + Node.SectorCount.QuadPart;
00556             Upper.RunStartVbn.QuadPart = EndHole.QuadPart;
00557             Upper.StartingLbn.QuadPart = 
00558                 Element->StartingLbn.QuadPart + 
00559                 EndHole.QuadPart - 
00560                 Element->RunStartVbn.QuadPart;
00561             Upper.SectorCount.QuadPart = 
00562                 Element->SectorCount.QuadPart -
00563                 (EndHole.QuadPart - Element->RunStartVbn.QuadPart);
00564             Reinsert = *Element;
00565             Reinsert.SectorCount.QuadPart = 
00566                 Element->RunStartVbn.QuadPart - StartHole.QuadPart;
00567             RemoveEntryList(&Element->Sequence);
00568             RtlDeleteElementGenericTable(Mcb->Mapping, Element);
00569             Mcb->PairCount--;
00570 
00571             Reinserted = RtlInsertElementGenericTable
00572                 (Mcb->Mapping, &Reinsert, sizeof(Reinsert), NULL);
00573             InsertHeadList(GET_LIST_HEAD(Mcb->Mapping), &Reinserted->Sequence);
00574             Mcb->PairCount++;
00575             
00576             Inserted = RtlInsertElementGenericTable
00577                 (Mcb->Mapping, &Upper, sizeof(Upper), NULL);
00578             InsertHeadList(GET_LIST_HEAD(Mcb->Mapping), &Inserted->Sequence);
00579             Mcb->PairCount++;
00580         }
00581         else if (Element->RunStartVbn.QuadPart < Node.RunStartVbn.QuadPart)
00582         {
00583             LARGE_MCB_MAPPING_ENTRY NewElement;
00584             PLARGE_MCB_MAPPING_ENTRY Reinserted;
00585             LARGE_INTEGER StartHole = Node.RunStartVbn;
00586             NewElement.RunStartVbn = Element->RunStartVbn;
00587             NewElement.StartingLbn = Element->StartingLbn;
00588             NewElement.SectorCount.QuadPart = StartHole.QuadPart - Element->StartingLbn.QuadPart;
00589 
00590             RemoveEntryList(&Element->Sequence);
00591             RtlDeleteElementGenericTable(Mcb->Mapping, Element);
00592             Mcb->PairCount--;
00593             
00594             Reinserted = RtlInsertElementGenericTable
00595                 (Mcb->Mapping, &NewElement, sizeof(NewElement), NULL);
00596             InsertHeadList(GET_LIST_HEAD(Mcb->Mapping), &Reinserted->Sequence);
00597             Mcb->PairCount++;           
00598         }
00599         else
00600         {
00601             LARGE_MCB_MAPPING_ENTRY NewElement;
00602             PLARGE_MCB_MAPPING_ENTRY Reinserted;
00603             LARGE_INTEGER EndHole = Element->RunStartVbn;
00604             LARGE_INTEGER EndRun;
00605             EndRun.QuadPart = Element->RunStartVbn.QuadPart + Element->SectorCount.QuadPart;
00606             NewElement.RunStartVbn = EndHole;
00607             NewElement.StartingLbn.QuadPart = Element->StartingLbn.QuadPart + 
00608                 (EndHole.QuadPart - Element->RunStartVbn.QuadPart);
00609             NewElement.SectorCount.QuadPart = EndRun.QuadPart - EndHole.QuadPart;
00610 
00611             RemoveEntryList(&Element->Sequence);
00612             RtlDeleteElementGenericTable(Mcb->Mapping, Element);
00613             Mcb->PairCount--;
00614             
00615             Reinserted = RtlInsertElementGenericTable
00616                 (Mcb->Mapping, &NewElement, sizeof(NewElement), NULL);
00617             InsertHeadList(GET_LIST_HEAD(Mcb->Mapping), &Reinserted->Sequence);
00618             Mcb->PairCount++;           
00619         }
00620     }
00621 
00622     return TRUE;
00623 }
00624 
00625 /*
00626  * @implemented
00627  */
00628 VOID
00629 NTAPI
00630 FsRtlRemoveLargeMcbEntry(IN PLARGE_MCB Mcb,
00631                          IN LONGLONG Vbn,
00632                          IN LONGLONG SectorCount)
00633 {
00634     DPRINT("FsRtlRemoveLargeMcbEntry Mcb %x, Vbn %x, SectorCount %x\n", Mcb, (ULONG)Vbn, (ULONG)SectorCount);
00635 
00636     KeAcquireGuardedMutex(Mcb->GuardedMutex);
00637     FsRtlRemoveBaseMcbEntry(&(Mcb->BaseMcb),
00638                             Vbn,
00639                             SectorCount);
00640     KeReleaseGuardedMutex(Mcb->GuardedMutex);
00641 
00642     DPRINT("Done\n");
00643 }
00644 
00645 /*
00646  * @implemented
00647  */
00648 VOID
00649 NTAPI
00650 FsRtlResetBaseMcb(IN PBASE_MCB Mcb)
00651 {
00652     PLARGE_MCB_MAPPING_ENTRY Element;
00653 
00654     while (RtlNumberGenericTableElements(Mcb->Mapping) &&
00655            (Element = (PLARGE_MCB_MAPPING_ENTRY)RtlGetElementGenericTable(Mcb->Mapping, 0)))
00656     {
00657         RtlDeleteElementGenericTable(Mcb->Mapping, Element);
00658     }
00659 
00660     Mcb->PairCount = 0;
00661     Mcb->MaximumPairCount = 0;
00662 }
00663 
00664 /*
00665  * @implemented
00666  */
00667 VOID
00668 NTAPI
00669 FsRtlResetLargeMcb(IN PLARGE_MCB Mcb,
00670                    IN BOOLEAN SelfSynchronized)
00671 {
00672     if (!SelfSynchronized)
00673     {
00674         KeAcquireGuardedMutex(Mcb->GuardedMutex);
00675     }
00676 
00677     FsRtlResetBaseMcb(&Mcb->BaseMcb);
00678 
00679 
00680     if (!SelfSynchronized)
00681     {
00682         KeReleaseGuardedMutex(Mcb->GuardedMutex);
00683     }
00684 }
00685 
00686 #define MCB_BUMP_NO_MORE 0
00687 #define MCB_BUMP_AGAIN   1
00688 
00689 static ULONG NTAPI McbBump(PBASE_MCB Mcb, PLARGE_MCB_MAPPING_ENTRY FixedPart)
00690 {
00691     LARGE_MCB_MAPPING_ENTRY Reimagined;
00692     PLARGE_MCB_MAPPING_ENTRY Found = NULL;
00693 
00694     DPRINT("McbBump %x (%x:%x)\n", Mcb, FixedPart->RunStartVbn.LowPart, FixedPart->SectorCount.LowPart);
00695 
00696     Reimagined = *FixedPart;
00697     while ((Found = RtlLookupElementGenericTable(Mcb->Mapping, &Reimagined)))
00698     {
00699         Reimagined = *Found;
00700         Reimagined.RunStartVbn.QuadPart = 
00701             FixedPart->RunStartVbn.QuadPart + FixedPart->SectorCount.QuadPart;
00702         DPRINT("Reimagined %x\n", Reimagined.RunStartVbn.LowPart);
00703     }
00704 
00705     DPRINT("Found %x\n", Found);
00706     if (!Found) return MCB_BUMP_NO_MORE;
00707     DPRINT1
00708         ("Moving %x-%x to %x because %x-%x overlaps\n",
00709          Found->RunStartVbn.LowPart, 
00710          Found->RunStartVbn.LowPart + Found->SectorCount.QuadPart,
00711          Reimagined.RunStartVbn.LowPart + Reimagined.SectorCount.LowPart,
00712          Reimagined.RunStartVbn.LowPart,
00713          Reimagined.RunStartVbn.LowPart + Reimagined.SectorCount.LowPart);
00714     Found->RunStartVbn.QuadPart = Reimagined.RunStartVbn.QuadPart + Reimagined.SectorCount.QuadPart;
00715     Found->StartingLbn.QuadPart = Reimagined.StartingLbn.QuadPart + Reimagined.SectorCount.QuadPart;
00716 
00717     DPRINT("Again\n");
00718     return MCB_BUMP_AGAIN;
00719 }
00720 
00721 /*
00722  * @unimplemented
00723  */
00724 BOOLEAN
00725 NTAPI
00726 FsRtlSplitBaseMcb(IN PBASE_MCB Mcb,
00727                   IN LONGLONG Vbn,
00728                   IN LONGLONG Amount)
00729 {
00730     ULONG Result;
00731     LARGE_MCB_MAPPING_ENTRY Node;
00732     PLARGE_MCB_MAPPING_ENTRY Existing = NULL;
00733 
00734     Node.RunStartVbn.QuadPart = Vbn;
00735     Node.SectorCount.QuadPart = 0;
00736     
00737     Existing = RtlLookupElementGenericTable(Mcb->Mapping, &Node);
00738 
00739     if (Existing)
00740     {
00741         // We're in the middle of a run
00742         LARGE_MCB_MAPPING_ENTRY UpperPart;
00743         LARGE_MCB_MAPPING_ENTRY LowerPart;
00744         PLARGE_MCB_MAPPING_ENTRY InsertedUpper;
00745 
00746         UpperPart.RunStartVbn.QuadPart = Node.RunStartVbn.QuadPart + Amount;
00747         UpperPart.SectorCount.QuadPart = Existing->RunStartVbn.QuadPart + 
00748             (Existing->SectorCount.QuadPart - Node.RunStartVbn.QuadPart);
00749         UpperPart.StartingLbn.QuadPart = Existing->StartingLbn.QuadPart + 
00750             (Node.RunStartVbn.QuadPart - Existing->RunStartVbn.QuadPart);
00751         LowerPart.RunStartVbn.QuadPart = Existing->RunStartVbn.QuadPart;
00752         LowerPart.SectorCount.QuadPart = Node.RunStartVbn.QuadPart - Existing->RunStartVbn.QuadPart;
00753         LowerPart.StartingLbn.QuadPart = Existing->StartingLbn.QuadPart;
00754         
00755         Node = UpperPart;
00756 
00757         DPRINT("Loop: %x\n", Node.RunStartVbn.LowPart);
00758         while ((Result = McbBump(Mcb, &Node)) == MCB_BUMP_AGAIN)
00759         {
00760             DPRINT("Node: %x\n", Node.RunStartVbn.LowPart);
00761         }
00762         DPRINT("Done\n");
00763 
00764         if (Result == MCB_BUMP_NO_MORE)
00765         {
00766             Node = *Existing;
00767             RemoveHeadList(&Existing->Sequence);
00768             RtlDeleteElementGenericTable(Mcb->Mapping, Existing);
00769             Mcb->PairCount--;
00770             
00771             // Adjust the element we found.
00772             Existing->SectorCount = LowerPart.SectorCount;
00773 
00774             InsertedUpper = RtlInsertElementGenericTable
00775                 (Mcb->Mapping, &UpperPart, sizeof(UpperPart), NULL);
00776             if (!InsertedUpper)
00777             {
00778                 // Just make it like it was
00779                 Existing->SectorCount = Node.SectorCount;
00780                 return FALSE;
00781             }
00782             InsertHeadList(GET_LIST_HEAD(Mcb->Mapping), &InsertedUpper->Sequence);
00783             Mcb->PairCount++;
00784         }
00785         else
00786         {
00787             Node.RunStartVbn.QuadPart = Vbn;
00788             Node.SectorCount.QuadPart = Amount;
00789             while ((Result = McbBump(Mcb, &Node)) == MCB_BUMP_AGAIN);
00790             return Result == MCB_BUMP_NO_MORE;
00791         }
00792     }
00793 
00794     DPRINT("Done\n");
00795     
00796     return TRUE;
00797 }
00798 
00799 /*
00800  * @implemented
00801  */
00802 BOOLEAN
00803 NTAPI
00804 FsRtlSplitLargeMcb(IN PLARGE_MCB Mcb,
00805                    IN LONGLONG Vbn,
00806                    IN LONGLONG Amount)
00807 {
00808     BOOLEAN Result;
00809 
00810     DPRINT("FsRtlSplitLargeMcb %x, Vbn %x, Amount %x\n", Mcb, (ULONG)Vbn, (ULONG)Amount);
00811 
00812     KeAcquireGuardedMutex(Mcb->GuardedMutex);
00813     Result = FsRtlSplitBaseMcb(&(Mcb->BaseMcb),
00814                                Vbn,
00815                                Amount);
00816     KeReleaseGuardedMutex(Mcb->GuardedMutex);
00817 
00818     DPRINT("Done %d\n", Result);
00819 
00820     return Result;
00821 }
00822 
00823 /*
00824  * @unimplemented
00825  */
00826 VOID
00827 NTAPI
00828 FsRtlTruncateBaseMcb(IN PBASE_MCB Mcb,
00829                      IN LONGLONG Vbn)
00830 {
00831     if (!Vbn)
00832     {
00833         FsRtlResetBaseMcb(Mcb);
00834     }
00835     else
00836     {
00837         LARGE_MCB_MAPPING_ENTRY Truncate;
00838         PLARGE_MCB_MAPPING_ENTRY Found;
00839         Truncate.RunStartVbn.QuadPart = Vbn;
00840         Truncate.SectorCount.QuadPart = (1ull<<62) - Truncate.RunStartVbn.QuadPart;
00841         while ((Found = RtlLookupElementGenericTable(Mcb->Mapping, &Truncate)))
00842         {
00843             RemoveEntryList(&Found->Sequence);
00844             RtlDeleteElementGenericTable(Mcb->Mapping, Found);
00845             Mcb->PairCount--;
00846         }
00847     }
00848 }
00849 
00850 /*
00851  * @implemented
00852  */
00853 VOID
00854 NTAPI
00855 FsRtlTruncateLargeMcb(IN PLARGE_MCB Mcb,
00856                       IN LONGLONG Vbn)
00857 {
00858     DPRINT("FsRtlTruncateLargeMcb %x Vbn %x\n", Mcb, (ULONG)Vbn);
00859     KeAcquireGuardedMutex(Mcb->GuardedMutex);
00860     FsRtlTruncateBaseMcb(&(Mcb->BaseMcb),
00861                          Vbn);
00862     KeReleaseGuardedMutex(Mcb->GuardedMutex);
00863     DPRINT("Done\n");
00864 }
00865 
00866 /*
00867  * @implemented
00868  */
00869 VOID
00870 NTAPI
00871 FsRtlUninitializeBaseMcb(IN PBASE_MCB Mcb)
00872 {
00873     FsRtlResetBaseMcb(Mcb);
00874 
00875     if ((Mcb->PoolType == PagedPool) && (Mcb->MaximumPairCount == MAXIMUM_PAIR_COUNT))
00876     {
00877         ExFreeToPagedLookasideList(&FsRtlFirstMappingLookasideList,
00878                                    Mcb->Mapping);
00879     }
00880     else
00881     {
00882         ExFreePoolWithTag(Mcb->Mapping, 'FSBC');
00883     }
00884 }
00885 
00886 /*
00887  * @implemented
00888  */
00889 VOID
00890 NTAPI
00891 FsRtlUninitializeLargeMcb(IN PLARGE_MCB Mcb)
00892 {
00893     if (Mcb->GuardedMutex)
00894     {
00895         ExFreeToNPagedLookasideList(&FsRtlFastMutexLookasideList,
00896                                     Mcb->GuardedMutex);
00897         FsRtlUninitializeBaseMcb(&(Mcb->BaseMcb));
00898     }
00899 }
00900 

Generated on Sun May 27 2012 04:37:11 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.