[NTOSKRNL] Drop the alloc map from page file
[reactos.git] / ntoskrnl / mm / pagefile.c
index bbf3d94..b5f9c4f 100644 (file)
@@ -271,19 +271,6 @@ MmInitPagingFile(VOID)
     MmNumberOfPagingFiles = 0;
 }
 
-static ULONG
-MiAllocPageFromPagingFile(PMMPAGING_FILE PagingFile)
-{
-    KIRQL oldIrql;
-    ULONG off;
-
-    KeAcquireSpinLock(&PagingFile->AllocMapLock, &oldIrql);
-    off = RtlFindClearBitsAndSet(PagingFile->AllocMap, 1, 0);
-    KeReleaseSpinLock(&PagingFile->AllocMapLock, oldIrql);
-
-    return off;
-}
-
 VOID
 NTAPI
 MmFreeSwapPage(SWAPENTRY Entry)
@@ -303,7 +290,6 @@ MmFreeSwapPage(SWAPENTRY Entry)
     {
         KeBugCheck(MEMORY_MANAGEMENT);
     }
-    KeAcquireSpinLockAtDpcLevel(&PagingFile->AllocMapLock);
 
     RtlClearBit(PagingFile->AllocMap, off >> 5);
 
@@ -313,7 +299,6 @@ MmFreeSwapPage(SWAPENTRY Entry)
     MiFreeSwapPages++;
     MiUsedSwapPages--;
 
-    KeReleaseSpinLockFromDpcLevel(&PagingFile->AllocMapLock);
     KeReleaseSpinLock(&PagingFileListLock, oldIrql);
 }
 
@@ -339,7 +324,7 @@ MmAllocSwapPage(VOID)
         if (MmPagingFile[i] != NULL &&
                 MmPagingFile[i]->FreePages >= 1)
         {
-            off = MiAllocPageFromPagingFile(MmPagingFile[i]);
+            off = RtlFindClearBitsAndSet(MmPagingFile[i]->AllocMap, 1, 0);
             if (off == 0xFFFFFFFF)
             {
                 KeBugCheck(MEMORY_MANAGEMENT);
@@ -571,9 +556,12 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName,
     /* If we failed, relax a bit constraints, someone may be already holding the
      * the file, so share write, don't attempt to replace and don't delete on close
      * (basically, don't do anything conflicting)
+     * This can happen if the caller attempts to extend a page file.
      */
     if (!NT_SUCCESS(Status))
     {
+        ULONG i;
+
         Status = IoCreateFile(&FileHandle,
                               SYNCHRONIZE | FILE_WRITE_DATA,
                               &ObjectAttributes,
@@ -588,6 +576,67 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName,
                               CreateFileTypeNone,
                               NULL,
                               SL_OPEN_PAGING_FILE | IO_NO_PARAMETER_CHECKING);
+        if (!NT_SUCCESS(Status))
+        {
+            ExFreePoolWithTag(Dacl, 'lcaD');
+            ExFreePoolWithTag(Buffer, TAG_MM);
+            return Status;
+        }
+
+        /* We opened it! Check we are that "someone" ;-)
+         * First, get the opened file object.
+         */
+        Status = ObReferenceObjectByHandle(FileHandle,
+                                           FILE_READ_DATA | FILE_WRITE_DATA,
+                                           IoFileObjectType,
+                                           KernelMode,
+                                           (PVOID*)&FileObject,
+                                           NULL);
+        if (!NT_SUCCESS(Status))
+        {
+            ZwClose(FileHandle);
+            ExFreePoolWithTag(Dacl, 'lcaD');
+            ExFreePoolWithTag(Buffer, TAG_MM);
+            return Status;
+        }
+
+        /* Find if it matches a previous page file */
+        PagingFile = NULL;
+        if (MmNumberOfPagingFiles > 0)
+        {
+            i = 0;
+
+            while (MmPagingFile[i]->FileObject->SectionObjectPointer != FileObject->SectionObjectPointer)
+            {
+                ++i;
+                if (i >= MmNumberOfPagingFiles)
+                {
+                    break;
+                }
+            }
+
+            /* This is the matching page file */
+            PagingFile = MmPagingFile[i];
+        }
+
+        /* If we didn't find the page file, fail */
+        if (PagingFile == NULL)
+        {
+            ObDereferenceObject(FileObject);
+            ZwClose(FileHandle);
+            ExFreePoolWithTag(Dacl, 'lcaD');
+            ExFreePoolWithTag(Buffer, TAG_MM);
+            return STATUS_NOT_FOUND;
+        }
+
+        /* FIXME: implement parameters checking and page file extension */
+        UNIMPLEMENTED;
+
+        ObDereferenceObject(FileObject);
+        ZwClose(FileHandle);
+        ExFreePoolWithTag(Dacl, 'lcaD');
+        ExFreePoolWithTag(Buffer, TAG_MM);
+        return STATUS_NOT_IMPLEMENTED;
     }
 
     if (!NT_SUCCESS(Status))
@@ -668,7 +717,6 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName,
     PagingFile->CurrentSize.QuadPart = SafeInitialSize.QuadPart;
     PagingFile->FreePages = (ULONG)(SafeInitialSize.QuadPart / PAGE_SIZE);
     PagingFile->UsedPages = 0;
-    KeInitializeSpinLock(&PagingFile->AllocMapLock);
     PagingFile->PageFileName = PageFileName;
 
     AllocMapSize = sizeof(RTL_BITMAP) + (((PagingFile->FreePages + 31) / 32) * sizeof(ULONG));