]> git.proxmox.com Git - mirror_edk2.git/blobdiff - FatPkg/EnhancedFatDxe/FileSpace.c
MdeModulePkg/FaultTolerantWriteDxe: implement standalone MM version
[mirror_edk2.git] / FatPkg / EnhancedFatDxe / FileSpace.c
index db44a331a84b6af26e80e9bc61a12750954359f3..e17d3b65316a3fc03556703493910d06caab9e1a 100644 (file)
@@ -1,4 +1,5 @@
-/*++\r
+/** @file\r
+  Routines dealing with disk spaces and FAT table entries.\r
 \r
 Copyright (c) 2005 - 2013, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials are licensed and made available\r
@@ -10,43 +11,28 @@ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
 \r
 \r
-Module Name:\r
 \r
-  FileSpace.c\r
+**/\r
 \r
-Abstract:\r
+#include "Fat.h"\r
 \r
-  Routines dealing with disk spaces and FAT table entries\r
 \r
-Revision History\r
+/**\r
 \r
---*/\r
+  Get the FAT entry of the volume, which is identified with the Index.\r
 \r
-#include "Fat.h"\r
+  @param  Volume                - FAT file system volume.\r
+  @param  Index                 - The index of the FAT entry of the volume.\r
 \r
+  @return The buffer of the FAT entry\r
 \r
+**/\r
 STATIC\r
 VOID *\r
 FatLoadFatEntry (\r
   IN FAT_VOLUME       *Volume,\r
   IN UINTN            Index\r
   )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Get the FAT entry of the volume, which is identified with the Index.\r
-\r
-Arguments:\r
-\r
-  Volume                - FAT file system volume.\r
-  Index                 - The index of the FAT entry of the volume.\r
-\r
-Returns:\r
-\r
-  The buffer of the FAT entry\r
-\r
---*/\r
 {\r
   UINTN       Pos;\r
   EFI_STATUS  Status;\r
@@ -89,28 +75,22 @@ Returns:
   return &Volume->FatEntryBuffer;\r
 }\r
 \r
+/**\r
+\r
+  Get the FAT entry value of the volume, which is identified with the Index.\r
+\r
+  @param  Volume                - FAT file system volume.\r
+  @param  Index                 - The index of the FAT entry of the volume.\r
+\r
+  @return  The value of the FAT entry.\r
+\r
+**/\r
 STATIC\r
 UINTN\r
 FatGetFatEntry (\r
   IN FAT_VOLUME       *Volume,\r
   IN UINTN            Index\r
   )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Get the FAT entry value of the volume, which is identified with the Index.\r
-\r
-Arguments:\r
-\r
-  Volume                - FAT file system volume.\r
-  Index                 - The index of the FAT entry of the volume.\r
-\r
-Returns:\r
-\r
-  The value of the FAT entry.\r
-\r
---*/\r
 {\r
   VOID    *Pos;\r
   UINT8   *En12;\r
@@ -147,6 +127,19 @@ Returns:
   return Accum;\r
 }\r
 \r
+/**\r
+\r
+  Set the FAT entry value of the volume, which is identified with the Index.\r
+\r
+  @param  Volume                - FAT file system volume.\r
+  @param  Index                 - The index of the FAT entry of the volume.\r
+  @param  Value                 - The new value of the FAT entry.\r
+\r
+  @retval EFI_SUCCESS           - Set the new FAT entry value sucessfully.\r
+  @retval EFI_VOLUME_CORRUPTED  - The FAT type of the volume is error.\r
+  @return other                 - An error occurred when operation the FAT entries.\r
+\r
+**/\r
 STATIC\r
 EFI_STATUS\r
 FatSetFatEntry (\r
@@ -154,25 +147,6 @@ FatSetFatEntry (
   IN UINTN            Index,\r
   IN UINTN            Value\r
   )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Set the FAT entry value of the volume, which is identified with the Index.\r
-\r
-Arguments:\r
-\r
-  Volume                - FAT file system volume.\r
-  Index                 - The index of the FAT entry of the volume.\r
-  Value                 - The new value of the FAT entry.\r
-\r
-Returns:\r
-\r
-  EFI_SUCCESS           - Set the new FAT entry value sucessfully.\r
-  EFI_VOLUME_CORRUPTED  - The FAT type of the volume is error.\r
-  other                 - An error occurred when operation the FAT entries.\r
-\r
---*/\r
 {\r
   VOID        *Pos;\r
   UINT8       *En12;\r
@@ -253,29 +227,23 @@ Returns:
   return Status;\r
 }\r
 \r
+/**\r
+\r
+  Free the cluster clain.\r
+\r
+  @param  Volume                - FAT file system volume.\r
+  @param  Cluster               - The first cluster of cluster chain.\r
+\r
+  @retval EFI_SUCCESS           - The cluster chain is freed successfully.\r
+  @retval EFI_VOLUME_CORRUPTED  - There are errors in the file's clusters.\r
+\r
+**/\r
 STATIC\r
 EFI_STATUS\r
 FatFreeClusters (\r
   IN FAT_VOLUME           *Volume,\r
   IN UINTN                Cluster\r
   )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Free the cluster clain.\r
-\r
-Arguments:\r
-\r
-  Volume                - FAT file system volume.\r
-  Cluster               - The first cluster of cluster chain.\r
-\r
-Returns:\r
-\r
-  EFI_SUCCESS           - The cluster chain is freed successfully.\r
-  EFI_VOLUME_CORRUPTED  - There are errors in the file's clusters.\r
-\r
---*/\r
 {\r
   UINTN LastCluster;\r
 \r
@@ -294,26 +262,20 @@ Returns:
   return EFI_SUCCESS;\r
 }\r
 \r
-STATIC\r
-UINTN\r
-FatAllocateCluster (\r
-  IN FAT_VOLUME   *Volume\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
+/**\r
 \r
   Allocate a free cluster and return the cluster index.\r
 \r
-Arguments:\r
-\r
-  Volume                - FAT file system volume.\r
-\r
-Returns:\r
+  @param  Volume                - FAT file system volume.\r
 \r
-  The index of the free cluster\r
+  @return The index of the free cluster\r
 \r
---*/\r
+**/\r
+STATIC\r
+UINTN\r
+FatAllocateCluster (\r
+  IN FAT_VOLUME   *Volume\r
+  )\r
 {\r
   UINTN Cluster;\r
 \r
@@ -354,28 +316,22 @@ Returns:
   return Cluster;\r
 }\r
 \r
+/**\r
+\r
+  Count the number of clusters given a size.\r
+\r
+  @param  Volume                - The file system volume.\r
+  @param  Size                  - The size in bytes.\r
+\r
+  @return The number of the clusters.\r
+\r
+**/\r
 STATIC\r
 UINTN\r
 FatSizeToClusters (\r
   IN FAT_VOLUME       *Volume,\r
   IN UINTN            Size\r
   )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Count the number of clusters given a size\r
-\r
-Arguments:\r
-\r
-  Volume                - The file system volume.\r
-  Size                  - The size in bytes.\r
-\r
-Returns:\r
-\r
-  The number of the clusters.\r
-\r
---*/\r
 {\r
   UINTN Clusters;\r
 \r
@@ -387,26 +343,20 @@ Returns:
   return Clusters;\r
 }\r
 \r
-EFI_STATUS\r
-FatShrinkEof (\r
-  IN FAT_OFILE            *OFile\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
+/**\r
 \r
   Shrink the end of the open file base on the file size.\r
 \r
-Arguments:\r
+  @param  OFile                 - The open file.\r
 \r
-  OFile                 - The open file.\r
+  @retval EFI_SUCCESS           - Shrinked sucessfully.\r
+  @retval EFI_VOLUME_CORRUPTED  - There are errors in the file's clusters.\r
 \r
-Returns:\r
-\r
-  EFI_SUCCESS           - Shrinked sucessfully.\r
-  EFI_VOLUME_CORRUPTED  - There are errors in the file's clusters.\r
-\r
---*/\r
+**/\r
+EFI_STATUS\r
+FatShrinkEof (\r
+  IN FAT_OFILE            *OFile\r
+  )\r
 {\r
   FAT_VOLUME  *Volume;\r
   UINTN       NewSize;\r
@@ -465,30 +415,24 @@ Returns:
   return FatFreeClusters (Volume, Cluster);\r
 }\r
 \r
-EFI_STATUS\r
-FatGrowEof (\r
-  IN FAT_OFILE            *OFile,\r
-  IN UINT64               NewSizeInBytes\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
+/**\r
 \r
   Grow the end of the open file base on the NewSizeInBytes.\r
 \r
-Arguments:\r
-\r
-  OFile                 - The open file.\r
-  NewSizeInBytes        - The new size in bytes of the open file.\r
+  @param  OFile                 - The open file.\r
+  @param  NewSizeInBytes        - The new size in bytes of the open file.\r
 \r
-Returns:\r
+  @retval EFI_SUCCESS           - The file is grown sucessfully.\r
+  @retval EFI_UNSUPPORTED       - The file size is larger than 4GB.\r
+  @retval EFI_VOLUME_CORRUPTED  - There are errors in the files' clusters.\r
+  @retval EFI_VOLUME_FULL       - The volume is full and can not grow the file.\r
 \r
-  EFI_SUCCESS           - The file is grown sucessfully.\r
-  EFI_UNSUPPORTED       - The file size is larger than 4GB.\r
-  EFI_VOLUME_CORRUPTED  - There are errors in the files' clusters.\r
-  EFI_VOLUME_FULL       - The volume is full and can not grow the file.\r
-\r
---*/\r
+**/\r
+EFI_STATUS\r
+FatGrowEof (\r
+  IN FAT_OFILE            *OFile,\r
+  IN UINT64               NewSizeInBytes\r
+  )\r
 {\r
   FAT_VOLUME  *Volume;\r
   EFI_STATUS  Status;\r
@@ -523,7 +467,7 @@ Returns:
       ClusterCount  = 0;\r
 \r
       while (!FAT_END_OF_FAT_CHAIN (Cluster)) {\r
-        if (Cluster == FAT_CLUSTER_FREE || Cluster >= FAT_CLUSTER_SPECIAL) {\r
+        if (Cluster < FAT_MIN_CLUSTER || Cluster > Volume->MaxCluster + 1) {\r
 \r
           DEBUG (\r
             (EFI_D_INIT | EFI_D_ERROR,\r
@@ -565,6 +509,11 @@ Returns:
         goto Done;\r
       }\r
 \r
+      if (NewCluster < FAT_MIN_CLUSTER || NewCluster > Volume->MaxCluster + 1) {\r
+        Status = EFI_VOLUME_CORRUPTED;\r
+        goto Done;\r
+      }\r
+\r
       if (LastCluster != 0) {\r
         FatSetFatEntry (Volume, LastCluster, NewCluster);\r
       } else {\r
@@ -574,12 +523,21 @@ Returns:
 \r
       LastCluster = NewCluster;\r
       CurSize += 1;\r
+\r
+      //\r
+      // Terminate the cluster list\r
+      //\r
+      // Note that we must do this EVERY time we allocate a cluster, because\r
+      // FatAllocateCluster scans the FAT looking for a free cluster and\r
+      // "LastCluster" is no longer free!  Usually, FatAllocateCluster will\r
+      // start looking with the cluster after "LastCluster"; however, when\r
+      // there is only one free cluster left, it will find "LastCluster"\r
+      // a second time.  There are other, less predictable scenarios\r
+      // where this could happen, as well.\r
+      //\r
+      FatSetFatEntry (Volume, LastCluster, (UINTN) FAT_CLUSTER_LAST);\r
+      OFile->FileLastCluster = LastCluster;\r
     }\r
-    //\r
-    // Terminate the cluster list\r
-    //\r
-    FatSetFatEntry (Volume, LastCluster, (UINTN) FAT_CLUSTER_LAST);\r
-    OFile->FileLastCluster = LastCluster;\r
   }\r
 \r
   OFile->FileSize = (UINTN) NewSizeInBytes;\r
@@ -591,31 +549,25 @@ Done:
   return Status;\r
 }\r
 \r
-EFI_STATUS\r
-FatOFilePosition (\r
-  IN FAT_OFILE            *OFile,\r
-  IN UINTN                Position,\r
-  IN UINTN                PosLimit\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
+/**\r
 \r
   Seek OFile to requested position, and calculate the number of\r
   consecutive clusters from the position in the file\r
 \r
-Arguments:\r
-\r
-  OFile                 - The open file.\r
-  Position              - The file's position which will be accessed.\r
-  PosLimit              - The maximum length current reading/writing may access\r
+  @param  OFile                 - The open file.\r
+  @param  Position              - The file's position which will be accessed.\r
+  @param  PosLimit              - The maximum length current reading/writing may access\r
 \r
-Returns:\r
+  @retval EFI_SUCCESS           - Set the info successfully.\r
+  @retval EFI_VOLUME_CORRUPTED  - Cluster chain corrupt.\r
 \r
-  EFI_SUCCESS           - Set the info successfully.\r
-  EFI_VOLUME_CORRUPTED  - Cluster chain corrupt.\r
-\r
---*/\r
+**/\r
+EFI_STATUS\r
+FatOFilePosition (\r
+  IN FAT_OFILE            *OFile,\r
+  IN UINTN                Position,\r
+  IN UINTN                PosLimit\r
+  )\r
 {\r
   FAT_VOLUME  *Volume;\r
   UINTN       ClusterSize;\r
@@ -665,7 +617,7 @@ Returns:
       Cluster = FatGetFatEntry (Volume, Cluster);\r
     }\r
 \r
-    if (Cluster < FAT_MIN_CLUSTER) {\r
+    if (Cluster < FAT_MIN_CLUSTER || Cluster > Volume->MaxCluster + 1) {\r
       return EFI_VOLUME_CORRUPTED;\r
     }\r
 \r
@@ -691,28 +643,22 @@ Returns:
   return EFI_SUCCESS;\r
 }\r
 \r
-UINTN\r
-FatPhysicalDirSize (\r
-  IN FAT_VOLUME            *Volume,\r
-  IN UINTN                 Cluster\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Get the size of directory of the open file\r
+/**\r
 \r
-Arguments:\r
+  Get the size of directory of the open file.\r
 \r
-  Volume                - The File System Volume.\r
-  Cluster               - The Starting cluster.\r
+  @param  Volume                - The File System Volume.\r
+  @param  Cluster               - The Starting cluster.\r
 \r
-Returns:\r
-\r
-  The physical size of the file starting at the input cluster, if there is error in the\r
+  @return The physical size of the file starting at the input cluster, if there is error in the\r
   cluster chain, the return value is 0.\r
 \r
---*/\r
+**/\r
+UINTN\r
+FatPhysicalDirSize (\r
+  IN FAT_VOLUME            *Volume,\r
+  IN UINTN                 Cluster\r
+  )\r
 {\r
   UINTN Size;\r
   ASSERT_VOLUME_LOCKED (Volume);\r
@@ -742,27 +688,21 @@ Returns:
   return Size;\r
 }\r
 \r
+/**\r
+\r
+  Get the physical size of a file on the disk.\r
+\r
+  @param  Volume                - The file system volume.\r
+  @param  RealSize              - The real size of a file.\r
+\r
+  @return The physical size of a file on the disk.\r
+\r
+**/\r
 UINT64\r
 FatPhysicalFileSize (\r
   IN FAT_VOLUME            *Volume,\r
   IN UINTN                 RealSize\r
   )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Get the physical size of a file on the disk.\r
-\r
-Arguments:\r
-\r
-  Volume                - The file system volume.\r
-  RealSize              - The real size of a file.\r
-\r
-Returns:\r
-\r
-  The physical size of a file on the disk.\r
-\r
---*/\r
 {\r
   UINTN   ClusterSizeMask;\r
   UINT64  PhysicalSize;\r
@@ -771,25 +711,17 @@ Returns:
   return PhysicalSize;\r
 }\r
 \r
-VOID\r
-FatComputeFreeInfo (\r
-  IN FAT_VOLUME *Volume\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
+/**\r
 \r
   Update the free cluster info of FatInfoSector of the volume.\r
 \r
-Arguments:\r
-\r
-  Volume                - FAT file system volume.\r
-\r
-Returns:\r
-\r
-  None.\r
+  @param  Volume                - FAT file system volume.\r
 \r
---*/\r
+**/\r
+VOID\r
+FatComputeFreeInfo (\r
+  IN FAT_VOLUME *Volume\r
+  )\r
 {\r
   UINTN Index;\r
 \r