- Merge misaligned reads support (35998, 36834 by Art) from arty-newcc branch.
authorAleksey Bragin <aleksey@reactos.org>
Thu, 20 Nov 2008 20:02:36 +0000 (20:02 +0000)
committerAleksey Bragin <aleksey@reactos.org>
Thu, 20 Nov 2008 20:02:36 +0000 (20:02 +0000)
svn path=/trunk/; revision=37488

reactos/drivers/filesystems/cdfs/rw.c

index 86dc3e2..d1d1b58 100644 (file)
@@ -76,14 +76,23 @@ CdfsReadFile(PDEVICE_EXTENSION DeviceExt,
     {
       LARGE_INTEGER FileOffset;
       IO_STATUS_BLOCK IoStatus;
+      CC_FILE_SIZES FileSizes;
 
       if (ReadOffset + Length > Fcb->Entry.DataLengthL)
          Length = Fcb->Entry.DataLengthL - ReadOffset;
 
       if (FileObject->PrivateCacheMap == NULL)
        {
+         FileSizes.AllocationSize = Fcb->RFCB.AllocationSize;
+         FileSizes.FileSize = Fcb->RFCB.FileSize;
+         FileSizes.ValidDataLength = Fcb->RFCB.ValidDataLength;
+
+         DPRINT("Attach FCB to File: Size %08x%08x\n", 
+                Fcb->RFCB.ValidDataLength.HighPart,
+                Fcb->RFCB.ValidDataLength.LowPart);
+
           CcInitializeCacheMap(FileObject,
-                               (PCC_FILE_SIZES)(&Fcb->RFCB.AllocationSize),
+                               &FileSizes,
                               FALSE,
                               &(CdfsGlobalData->CacheMgrCallbacks),
                               Fcb);
@@ -103,25 +112,65 @@ CdfsReadFile(PDEVICE_EXTENSION DeviceExt,
 
   if ((ReadOffset % BLOCKSIZE) != 0 || (Length % BLOCKSIZE) != 0)
     {
-      return STATUS_INVALID_PARAMETER;
-    }
+      /* Then we need to do a partial or misaligned read ... */
+      PVOID PageBuf = ExAllocatePool(NonPagedPool, BLOCKSIZE);
+      PCHAR ReadInPage = (PCHAR)PageBuf + (ReadOffset & (BLOCKSIZE - 1));
+      PCHAR TargetRead = (PCHAR)Buffer;
+      ULONG ActualReadOffset, EndOfExtent, ReadLen;
+
+      if (!PageBuf)
+        {
+           return STATUS_NO_MEMORY;
+       }
 
-  if (ReadOffset + Length > ROUND_UP(Fcb->Entry.DataLengthL, BLOCKSIZE))
-    Length = ROUND_UP(Fcb->Entry.DataLengthL, BLOCKSIZE) - ReadOffset;
+      ActualReadOffset = ReadOffset & ~(BLOCKSIZE - 1);
+      EndOfExtent = ReadOffset + Length;
+
+      while (ActualReadOffset < EndOfExtent)
+        {
+         Status = CdfsReadSectors
+             (DeviceExt->StorageDevice,
+              Fcb->Entry.ExtentLocationL + (ActualReadOffset / BLOCKSIZE),
+              1,
+              PageBuf,
+              FALSE);
+         
+         if (!NT_SUCCESS(Status))
+           break;
+         
+         ReadLen = BLOCKSIZE - (ActualReadOffset & (BLOCKSIZE - 1));
+         if (ReadLen > EndOfExtent - ActualReadOffset)
+           {
+               ReadLen = EndOfExtent - ActualReadOffset;
+           }
+
+         RtlCopyMemory(TargetRead, ReadInPage, ReadLen);
+
+         ActualReadOffset += ReadLen;
+         TargetRead += ReadLen;          
+       }
 
-  Status = CdfsReadSectors(DeviceExt->StorageDevice,
-                          Fcb->Entry.ExtentLocationL + (ReadOffset / BLOCKSIZE),
-                          Length / BLOCKSIZE,
-                          Buffer,
-                          FALSE);
-  if (NT_SUCCESS(Status))
+      ExFreePool(PageBuf);
+    }
+  else
     {
-      *LengthRead = Length;
-      if (Length + ReadOffset > Fcb->Entry.DataLengthL)
-       {
-         memset(Buffer + Fcb->Entry.DataLengthL - ReadOffset,
-                0,
-                Length + ReadOffset - Fcb->Entry.DataLengthL);
+      if (ReadOffset + Length > ROUND_UP(Fcb->Entry.DataLengthL, BLOCKSIZE))
+       Length = ROUND_UP(Fcb->Entry.DataLengthL, BLOCKSIZE) - ReadOffset;
+
+      Status = CdfsReadSectors(DeviceExt->StorageDevice,
+                              Fcb->Entry.ExtentLocationL + (ReadOffset / BLOCKSIZE),
+                              Length / BLOCKSIZE,
+                              Buffer,
+                              FALSE);
+      if (NT_SUCCESS(Status))
+        {
+         *LengthRead = Length;
+         if (Length + ReadOffset > Fcb->Entry.DataLengthL)
+           {
+             memset(Buffer + Fcb->Entry.DataLengthL - ReadOffset,
+                    0,
+                    Length + ReadOffset - Fcb->Entry.DataLengthL);
+           }
        }
     }