[NTOSKRNL] Quickly check for alignment in NtRead/WriteFile
authorPierre Schweitzer <pierre@reactos.org>
Thu, 4 Oct 2018 08:42:13 +0000 (10:42 +0200)
committerPierre Schweitzer <pierre@reactos.org>
Thu, 4 Oct 2018 08:45:10 +0000 (10:45 +0200)
This quick check based on bits and operation is for 2^ based
sector sizes (most of the cases) and will perform faster than
the modulo operation which is still used in fallback in case
the sector size wouldn't be a power of 2.

ntoskrnl/io/iomgr/iofunc.c

index 01a9565..61fd88f 100644 (file)
@@ -2612,13 +2612,19 @@ NtReadFile(IN HANDLE FileHandle,
             /* Perform additional checks for non-cached file access */
             if (FileObject->Flags & FO_NO_INTERMEDIATE_BUFFERING)
             {
-                /* Fail if Length is not sector size aligned */
+                /* Fail if Length is not sector size aligned
+                 * Perform a quick check for 2^ sector sizes
+                 * If it fails, try a more standard way
+                 */
                 if ((DeviceObject->SectorSize != 0) &&
-                    (Length % DeviceObject->SectorSize != 0))
+                    ((DeviceObject->SectorSize - 1) & Length) != 0)
                 {
-                    /* Release the file object and and fail */
-                    ObDereferenceObject(FileObject);
-                    return STATUS_INVALID_PARAMETER;
+                    if (Length % DeviceObject->SectorSize != 0)
+                    {
+                        /* Release the file object and and fail */
+                        ObDereferenceObject(FileObject);
+                        return STATUS_INVALID_PARAMETER;
+                    }
                 }
 
                 /* Fail if buffer doesn't match alignment requirements */
@@ -3649,13 +3655,19 @@ NtWriteFile(IN HANDLE FileHandle,
             /* Perform additional checks for non-cached file access */
             if (FileObject->Flags & FO_NO_INTERMEDIATE_BUFFERING)
             {
-                /* Fail if Length is not sector size aligned */
+                /* Fail if Length is not sector size aligned
+                 * Perform a quick check for 2^ sector sizes
+                 * If it fails, try a more standard way
+                 */
                 if ((DeviceObject->SectorSize != 0) &&
-                    (Length % DeviceObject->SectorSize != 0))
+                    ((DeviceObject->SectorSize - 1) & Length) != 0)
                 {
-                    /* Release the file object and and fail */
-                    ObDereferenceObject(FileObject);
-                    return STATUS_INVALID_PARAMETER;
+                    if (Length % DeviceObject->SectorSize != 0)
+                    {
+                        /* Release the file object and and fail */
+                        ObDereferenceObject(FileObject);
+                        return STATUS_INVALID_PARAMETER;
+                    }
                 }
 
                 /* Fail if buffer doesn't match alignment requirements */