[edk2] [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix creation of UDF logical partition

Paulo Alcantara posted 2 patches 7 years, 3 months ago
There is a newer version of this series
[edk2] [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix creation of UDF logical partition
Posted by Paulo Alcantara 7 years, 3 months ago
Do not reserve entire block device size for an UDF file system -
instead, reserve the appropriate space (UDF logical volume space) for
it.

Additionally, only create a logical partition for UDF logical volumes
that are currently supported by EDK2 UDF file system implementation. For
instance, an UDF volume with a single LVD and a single Physical (Type 1)
Partition will be supported.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ruiyu Ni <ruiyu.ni@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Reported-by: Ruiyu Ni <ruiyu.ni@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Paulo Alcantara <pcacjr@zytor.com>
---
 MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c            | 363 ++++++++++--
 MdeModulePkg/Universal/Disk/UdfDxe/File.c                 |  16 +-
 MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c | 627 ++++++++------------
 MdeModulePkg/Universal/Disk/UdfDxe/Udf.c                  |   7 -
 MdeModulePkg/Universal/Disk/UdfDxe/Udf.h                  | 158 ++---
 5 files changed, 606 insertions(+), 565 deletions(-)

diff --git a/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c b/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
index 609f56cef6..572ba7a81a 100644
--- a/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
+++ b/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
@@ -64,11 +64,12 @@ FindAnchorVolumeDescriptorPointer (
   OUT  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint
   )
 {
-  EFI_STATUS  Status;
-  UINT32      BlockSize;
-  EFI_LBA     EndLBA;
-  EFI_LBA     DescriptorLBAs[4];
-  UINTN       Index;
+  EFI_STATUS          Status;
+  UINT32              BlockSize;
+  EFI_LBA             EndLBA;
+  EFI_LBA             DescriptorLBAs[4];
+  UINTN               Index;
+  UDF_DESCRIPTOR_TAG  *DescriptorTag;
 
   BlockSize = BlockIo->Media->BlockSize;
   EndLBA = BlockIo->Media->LastBlock;
@@ -88,10 +89,13 @@ FindAnchorVolumeDescriptorPointer (
     if (EFI_ERROR (Status)) {
       return Status;
     }
+
+    DescriptorTag = &AnchorPoint->DescriptorTag;
+
     //
     // Check if read LBA has a valid AVDP descriptor.
     //
-    if (IS_AVDP (AnchorPoint)) {
+    if (DescriptorTag->TagIdentifier == UdfAnchorVolumeDescriptorPointer) {
       return EFI_SUCCESS;
     }
   }
@@ -102,23 +106,18 @@ FindAnchorVolumeDescriptorPointer (
 }
 
 /**
-  Check if block device supports a valid UDF file system as specified by OSTA
-  Universal Disk Format Specification 2.60.
+  Find UDF volume identifiers in a Volume Recognition Sequence.
 
-  @param[in]   BlockIo  BlockIo interface.
-  @param[in]   DiskIo   DiskIo interface.
+  @param[in]  BlockIo             BlockIo interface.
+  @param[in]  DiskIo              DiskIo interface.
 
-  @retval EFI_SUCCESS          UDF file system found.
-  @retval EFI_UNSUPPORTED      UDF file system not found.
-  @retval EFI_NO_MEDIA         The device has no media.
-  @retval EFI_DEVICE_ERROR     The device reported an error.
-  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
-  @retval EFI_OUT_OF_RESOURCES The scan was not successful due to lack of
-                               resources.
+  @retval EFI_SUCCESS             UDF volume identifiers were found.
+  @retval EFI_NOT_FOUND           UDF volume identifiers were not found.
+  @retval other                   Failed to perform disk I/O.
 
 **/
 EFI_STATUS
-SupportUdfFileSystem (
+FindUdfVolumeIdentifiers (
   IN EFI_BLOCK_IO_PROTOCOL  *BlockIo,
   IN EFI_DISK_IO_PROTOCOL   *DiskIo
   )
@@ -128,7 +127,6 @@ SupportUdfFileSystem (
   UINT64                                EndDiskOffset;
   CDROM_VOLUME_DESCRIPTOR               VolDescriptor;
   CDROM_VOLUME_DESCRIPTOR               TerminatingVolDescriptor;
-  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  AnchorPoint;
 
   ZeroMem ((VOID *)&TerminatingVolDescriptor, sizeof (CDROM_VOLUME_DESCRIPTOR));
 
@@ -167,7 +165,7 @@ SupportUdfFileSystem (
         (CompareMem ((VOID *)&VolDescriptor,
                      (VOID *)&TerminatingVolDescriptor,
                      sizeof (CDROM_VOLUME_DESCRIPTOR)) == 0)) {
-      return EFI_UNSUPPORTED;
+      return EFI_NOT_FOUND;
     }
   }
 
@@ -176,7 +174,7 @@ SupportUdfFileSystem (
   //
   Offset += UDF_LOGICAL_SECTOR_SIZE;
   if (Offset >= EndDiskOffset) {
-    return EFI_UNSUPPORTED;
+    return EFI_NOT_FOUND;
   }
 
   Status = DiskIo->ReadDisk (
@@ -196,7 +194,7 @@ SupportUdfFileSystem (
       (CompareMem ((VOID *)VolDescriptor.Unknown.Id,
                    (VOID *)UDF_NSR3_IDENTIFIER,
                    sizeof (VolDescriptor.Unknown.Id)) != 0)) {
-    return EFI_UNSUPPORTED;
+    return EFI_NOT_FOUND;
   }
 
   //
@@ -204,7 +202,7 @@ SupportUdfFileSystem (
   //
   Offset += UDF_LOGICAL_SECTOR_SIZE;
   if (Offset >= EndDiskOffset) {
-    return EFI_UNSUPPORTED;
+    return EFI_NOT_FOUND;
   }
 
   Status = DiskIo->ReadDisk (
@@ -221,15 +219,291 @@ SupportUdfFileSystem (
   if (CompareMem ((VOID *)VolDescriptor.Unknown.Id,
                   (VOID *)UDF_TEA_IDENTIFIER,
                   sizeof (VolDescriptor.Unknown.Id)) != 0) {
-    return EFI_UNSUPPORTED;
+    return EFI_NOT_FOUND;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Check if Logical Volume Descriptor is supported by current EDK2 UDF file
+  system implementation.
+
+  @param[in]  LogicalVolDesc  Logical Volume Descriptor pointer.
+
+  @retval TRUE                Logical Volume Descriptor is supported.
+  @retval FALSE               Logical Volume Descriptor is not supported.
+
+**/
+BOOLEAN
+IsLogicalVolumeDescriptorSupported (
+  UDF_LOGICAL_VOLUME_DESCRIPTOR *LogicalVolDesc
+  )
+{
+  //
+  // Check for a valid UDF revision range
+  //
+  switch (UDF_LVD_REVISION (LogicalVolDesc)) {
+  case 0x0102:
+  case 0x0150:
+  case 0x0200:
+  case 0x0201:
+  case 0x0250:
+  case 0x0260:
+    break;
+  default:
+    return FALSE;
+  }
+
+  //
+  // Check for a single Partition Map
+  //
+  if (LogicalVolDesc->NumberOfPartitionMaps > 1) {
+    return FALSE;
+  }
+  //
+  // UDF 1.02 revision supports only Type 1 (Physical) partitions, but
+  // let's check it any way.
+  //
+  // PartitionMap[0] -> type
+  // PartitionMap[1] -> length (in bytes)
+  //
+  if (LogicalVolDesc->PartitionMaps[0] != 1 ||
+      LogicalVolDesc->PartitionMaps[1] != 6) {
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+/**
+  Find UDF logical volume location and whether it is supported by current EDK2
+  UDF file system implementation.
+
+  @param[in]  BlockIo             BlockIo interface.
+  @param[in]  DiskIo              DiskIo interface.
+  @param[in]  AnchorPoint         Anchor volume descriptor pointer.
+  @param[out] MainVdsStartBlock   Main VDS starting block number.
+  @param[out] MainVdsEndBlock     Main VDS ending block number.
+
+  @retval EFI_SUCCESS             UDF logical volume was found.
+  @retval EFI_VOLUME_CORRUPTED    UDF file system structures are corrupted.
+  @retval EFI_UNSUPPORTED         UDF logical volume is not supported.
+  @retval other                   Failed to perform disk I/O.
+
+**/
+EFI_STATUS
+FindLogicalVolumeLocation (
+  IN   EFI_BLOCK_IO_PROTOCOL                 *BlockIo,
+  IN   EFI_DISK_IO_PROTOCOL                  *DiskIo,
+  IN   UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint,
+  OUT  UINT64                                *MainVdsStartBlock,
+  OUT  UINT64                                *MainVdsEndBlock
+  )
+{
+  EFI_STATUS                     Status;
+  UINT32                         BlockSize;
+  EFI_LBA                        LastBlock;
+  UDF_EXTENT_AD                  *ExtentAd;
+  UINT64                         SeqBlocksNum;
+  UINT64                         SeqStartBlock;
+  UINT64                         GuardMainVdsStartBlock;
+  VOID                           *Buffer;
+  UINT64                         SeqEndBlock;
+  BOOLEAN                        StopSequence;
+  UINTN                          LvdsCount;
+  UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;
+  UDF_DESCRIPTOR_TAG             *DescriptorTag;
+
+  BlockSize = BlockIo->Media->BlockSize;
+  LastBlock = BlockIo->Media->LastBlock;
+  ExtentAd = &AnchorPoint->MainVolumeDescriptorSequenceExtent;
+
+  //
+  // UDF 2.60, 2.2.3.1 struct MainVolumeDescriptorSequenceExtent
+  //
+  // The Main Volume Descriptor Sequence Extent shall have a minimum length of
+  // 16 logical sectors.
+  //
+  // Also make sure it does not exceed maximum number of blocks in the disk.
+  //
+  SeqBlocksNum = DivU64x32 ((UINT64)ExtentAd->ExtentLength, BlockSize);
+  if (SeqBlocksNum < 16 || (EFI_LBA)SeqBlocksNum > LastBlock + 1) {
+    return EFI_VOLUME_CORRUPTED;
+  }
+
+  //
+  // Check for valid Volume Descriptor Sequence starting block number
+  //
+  SeqStartBlock = (UINT64)ExtentAd->ExtentLocation;
+  if (SeqStartBlock > LastBlock ||
+      SeqStartBlock + SeqBlocksNum - 1 > LastBlock) {
+    return EFI_VOLUME_CORRUPTED;
   }
 
+  GuardMainVdsStartBlock = SeqStartBlock;
+
+  //
+  // Allocate buffer for reading disk blocks
+  //
+  Buffer = AllocateZeroPool ((UINTN)BlockSize);
+  if (Buffer == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  SeqEndBlock = SeqStartBlock + SeqBlocksNum;
+  StopSequence = FALSE;
+  LvdsCount = 0;
+  Status = EFI_VOLUME_CORRUPTED;
+  //
+  // Start Main Volume Descriptor Sequence
+  //
+  for (; SeqStartBlock < SeqEndBlock && !StopSequence; SeqStartBlock++) {
+    //
+    // Read disk block
+    //
+    Status = BlockIo->ReadBlocks (
+      BlockIo,
+      BlockIo->Media->MediaId,
+      SeqStartBlock,
+      BlockSize,
+      Buffer
+      );
+    if (EFI_ERROR (Status)) {
+      goto Out_Free;
+    }
+
+    DescriptorTag = Buffer;
+
+    //
+    // ECMA 167, 8.4.1 Contents of a Volume Descriptor Sequence
+    //
+    // - A Volume Descriptor Sequence shall contain one or more Primary Volume
+    //   Descriptors.
+    // - A Volume Descriptor Sequence shall contain zero or more Implementation
+    //   Use Volume Descriptors.
+    // - A Volume Descriptor Sequence shall contain zero or more Partition
+    //   Descriptors.
+    // - A Volume Descriptor Sequence shall contain zero or more Logical Volume
+    //   Descriptors.
+    // - A Volume Descriptor Sequence shall contain zero or more Unallocated
+    //   Space Descriptors.
+    //
+    switch (UDF_TAG_ID (DescriptorTag)) {
+    case UdfPrimaryVolumeDescriptor:
+    case UdfImplemenationUseVolumeDescriptor:
+    case UdfPartitionDescriptor:
+    case UdfUnallocatedSpaceDescriptor:
+      break;
+
+    case UdfLogicalVolumeDescriptor:
+      LogicalVolDesc = Buffer;
+
+      //
+      // Check for existence of a single LVD and whether it is supported by
+      // current EDK2 UDF file system implementation.
+      //
+      if (++LvdsCount > 1 ||
+          !IsLogicalVolumeDescriptorSupported (LogicalVolDesc)) {
+        Status = EFI_UNSUPPORTED;
+        StopSequence = TRUE;
+      }
+
+      break;
+
+    case UdfTerminatingDescriptor:
+      //
+      // Stop the sequence when we find a Terminating Descriptor
+      // (aka Unallocated Sector), se we don't have to walk all the unallocated
+      // area unnecessarily.
+      //
+      StopSequence = TRUE;
+      break;
+
+    default:
+      //
+      // An invalid Volume Descriptor has been found in the sequece. Volume is
+      // corrupted.
+      //
+      Status = EFI_VOLUME_CORRUPTED;
+      goto Out_Free;
+    }
+  }
+
+  //
+  // Check if LVD was found
+  //
+  if (!EFI_ERROR (Status) && LvdsCount == 1) {
+    *MainVdsStartBlock = GuardMainVdsStartBlock;
+    //
+    // We do not need to read either LVD or PD descriptors to know the last
+    // valid block in the found UDF file system. It's already LastBlock.
+    //
+    *MainVdsEndBlock = LastBlock;
+
+    Status = EFI_SUCCESS;
+  }
+
+Out_Free:
+  //
+  // Free block read buffer
+  //
+  FreePool (Buffer);
+
+  return Status;
+}
+
+/**
+  Find a supported UDF file system in block device.
+
+  @param[in]  BlockIo             BlockIo interface.
+  @param[in]  DiskIo              DiskIo interface.
+  @param[out] StartingLBA         UDF file system starting LBA.
+  @param[out] EndingLBA           UDF file system starting LBA.
+
+  @retval EFI_SUCCESS             UDF file system was found.
+  @retval other                   UDF file system was not found.
+
+**/
+EFI_STATUS
+FindUdfFileSystem (
+  IN EFI_BLOCK_IO_PROTOCOL  *BlockIo,
+  IN EFI_DISK_IO_PROTOCOL   *DiskIo,
+  OUT EFI_LBA               *StartingLBA,
+  OUT EFI_LBA               *EndingLBA
+  )
+{
+  EFI_STATUS Status;
+  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  AnchorPoint;
+
+  //
+  // Find UDF volume identifiers
+  //
+  Status = FindUdfVolumeIdentifiers (BlockIo, DiskIo);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Find Anchor Volume Descriptor Pointer
+  //
   Status = FindAnchorVolumeDescriptorPointer (BlockIo, DiskIo, &AnchorPoint);
   if (EFI_ERROR (Status)) {
-    return EFI_UNSUPPORTED;
+    return Status;
   }
 
-  return EFI_SUCCESS;
+  //
+  // Find Logical Volume location
+  //
+  Status = FindLogicalVolumeLocation (
+    BlockIo,
+    DiskIo,
+    &AnchorPoint,
+    (UINT64 *)StartingLBA,
+    (UINT64 *)EndingLBA
+    );
+
+  return Status;
 }
 
 /**
@@ -263,9 +537,9 @@ PartitionInstallUdfChildHandles (
   UINT32                       RemainderByMediaBlockSize;
   EFI_STATUS                   Status;
   EFI_BLOCK_IO_MEDIA           *Media;
-  EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode;
-  EFI_GUID                     *VendorDefinedGuid;
   EFI_PARTITION_INFO_PROTOCOL  PartitionInfo;
+  EFI_LBA                      StartingLBA;
+  EFI_LBA                      EndingLBA;
 
   Media = BlockIo->Media;
 
@@ -281,35 +555,10 @@ PartitionInstallUdfChildHandles (
     return EFI_NOT_FOUND;
   }
 
-  DevicePathNode = DevicePath;
-  while (!IsDevicePathEnd (DevicePathNode)) {
-    //
-    // Do not allow checking for UDF file systems in CDROM "El Torito"
-    // partitions, and skip duplicate installation of UDF file system child
-    // nodes.
-    //
-    if (DevicePathType (DevicePathNode) == MEDIA_DEVICE_PATH) {
-      if (DevicePathSubType (DevicePathNode) == MEDIA_CDROM_DP) {
-        return EFI_NOT_FOUND;
-      }
-      if (DevicePathSubType (DevicePathNode) == MEDIA_VENDOR_DP) {
-        VendorDefinedGuid = (EFI_GUID *)((UINTN)DevicePathNode +
-                                         OFFSET_OF (VENDOR_DEVICE_PATH, Guid));
-        if (CompareGuid (VendorDefinedGuid, &gUdfDevPathGuid)) {
-          return EFI_NOT_FOUND;
-        }
-      }
-    }
-    //
-    // Try next device path node
-    //
-    DevicePathNode = NextDevicePathNode (DevicePathNode);
-  }
-
   //
-  // Check if block device supports an UDF file system
+  // Search for an UDF file system on block device
   //
-  Status = SupportUdfFileSystem (BlockIo, DiskIo);
+  Status = FindUdfFileSystem (BlockIo, DiskIo, &StartingLBA, &EndingLBA);
   if (EFI_ERROR (Status)) {
     return EFI_NOT_FOUND;
   }
@@ -334,8 +583,8 @@ PartitionInstallUdfChildHandles (
     DevicePath,
     (EFI_DEVICE_PATH_PROTOCOL *)&gUdfDevicePath,
     &PartitionInfo,
-    0,
-    Media->LastBlock,
+    StartingLBA,
+    EndingLBA,
     Media->BlockSize
     );
   if (!EFI_ERROR (Status)) {
diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/File.c b/MdeModulePkg/Universal/Disk/UdfDxe/File.c
index 625f2c5637..6f07bf2066 100644
--- a/MdeModulePkg/Universal/Disk/UdfDxe/File.c
+++ b/MdeModulePkg/Universal/Disk/UdfDxe/File.c
@@ -131,7 +131,6 @@ Error_Alloc_Priv_File_Data:
   CleanupFileInformation (&PrivFsData->Root);
 
 Error_Find_Root_Dir:
-  CleanupVolumeInformation (&PrivFsData->Volume);
 
 Error_Read_Udf_Volume:
 Error_Invalid_Params:
@@ -429,7 +428,7 @@ UdfRead (
     }
     ASSERT (NewFileEntryData != NULL);
 
-    if (IS_FE_SYMLINK (NewFileEntryData)) {
+    if (FE_ICB_FILE_TYPE (NewFileEntryData) == UdfFileEntrySymlink) {
       Status = ResolveSymlink (
         BlockIo,
         DiskIo,
@@ -529,7 +528,6 @@ UdfClose (
   EFI_TPL                     OldTpl;
   EFI_STATUS                  Status;
   PRIVATE_UDF_FILE_DATA       *PrivFileData;
-  PRIVATE_UDF_SIMPLE_FS_DATA  *PrivFsData;
 
   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
 
@@ -542,8 +540,6 @@ UdfClose (
 
   PrivFileData = PRIVATE_UDF_FILE_DATA_FROM_THIS (This);
 
-  PrivFsData = PRIVATE_UDF_SIMPLE_FS_DATA_FROM_THIS (PrivFileData->SimpleFs);
-
   if (!PrivFileData->IsRootDirectory) {
     CleanupFileInformation (&PrivFileData->File);
 
@@ -552,10 +548,6 @@ UdfClose (
     }
   }
 
-  if (--PrivFsData->OpenFiles == 0) {
-    CleanupVolumeInformation (&PrivFsData->Volume);
-  }
-
   FreePool ((VOID *)PrivFileData);
 
 Exit:
@@ -652,7 +644,7 @@ UdfGetPosition (
   // As per UEFI spec, if the file handle is a directory, then the current file
   // position has no meaning and the operation is not supported.
   //
-  if (IS_FID_DIRECTORY_FILE (&PrivFileData->File.FileIdentifierDesc)) {
+  if (IS_FID_DIRECTORY_FILE (PrivFileData->File.FileIdentifierDesc)) {
     return  EFI_UNSUPPORTED;
   }
 
@@ -788,7 +780,7 @@ UdfGetInfo (
   } else if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {
     String = VolumeLabel;
 
-    FileSetDesc = PrivFsData->Volume.FileSetDescs[0];
+    FileSetDesc = &PrivFsData->Volume.FileSetDesc;
 
     OstaCompressed = &FileSetDesc->LogicalVolumeIdentifier[0];
 
@@ -847,7 +839,7 @@ UdfGetInfo (
     FileSystemInfo->Size        = FileSystemInfoLength;
     FileSystemInfo->ReadOnly    = TRUE;
     FileSystemInfo->BlockSize   =
-      LV_BLOCK_SIZE (&PrivFsData->Volume, UDF_DEFAULT_LV_NUM);
+      PrivFsData->Volume.LogicalVolDesc.LogicalBlockSize;
     FileSystemInfo->VolumeSize  = VolumeSize;
     FileSystemInfo->FreeSpace   = FreeSpaceSize;
 
diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c b/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
index 5df267761f..62d817989f 100644
--- a/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
+++ b/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
@@ -38,11 +38,12 @@ FindAnchorVolumeDescriptorPointer (
   OUT  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint
   )
 {
-  EFI_STATUS  Status;
-  UINT32      BlockSize;
-  EFI_LBA     EndLBA;
-  EFI_LBA     DescriptorLBAs[4];
-  UINTN       Index;
+  EFI_STATUS          Status;
+  UINT32              BlockSize;
+  EFI_LBA             EndLBA;
+  EFI_LBA             DescriptorLBAs[4];
+  UINTN               Index;
+  UDF_DESCRIPTOR_TAG  *DescriptorTag;
 
   BlockSize = BlockIo->Media->BlockSize;
   EndLBA = BlockIo->Media->LastBlock;
@@ -62,10 +63,13 @@ FindAnchorVolumeDescriptorPointer (
     if (EFI_ERROR (Status)) {
       return Status;
     }
+
+    DescriptorTag = &AnchorPoint->DescriptorTag;
+
     //
     // Check if read LBA has a valid AVDP descriptor.
     //
-    if (IS_AVDP (AnchorPoint)) {
+    if (DescriptorTag->TagIdentifier == UdfAnchorVolumeDescriptorPointer) {
       return EFI_SUCCESS;
     }
   }
@@ -99,148 +103,98 @@ StartMainVolumeDescriptorSequence (
   OUT  UDF_VOLUME_INFO                       *Volume
   )
 {
-  EFI_STATUS                     Status;
-  UINT32                         BlockSize;
-  UDF_EXTENT_AD                  *ExtentAd;
-  UINT64                         StartingLsn;
-  UINT64                         EndingLsn;
-  VOID                           *Buffer;
-  UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;
-  UDF_PARTITION_DESCRIPTOR       *PartitionDesc;
-  UINTN                          Index;
-  UINT32                         LogicalBlockSize;
+  EFI_STATUS            Status;
+  UINT32                BlockSize;
+  UDF_EXTENT_AD         *ExtentAd;
+  EFI_LBA               SeqStartBlock;
+  EFI_LBA               SeqEndBlock;
+  BOOLEAN               StopSequence;
+  VOID                  *Buffer;
+  UDF_DESCRIPTOR_TAG    *DescriptorTag;
+  UINT32                LogicalBlockSize;
+
+  BlockSize = BlockIo->Media->BlockSize;
+  ExtentAd = &AnchorPoint->MainVolumeDescriptorSequenceExtent;
 
   //
-  // We've already found an ADVP on the volume. It contains the extent
-  // (MainVolumeDescriptorSequenceExtent) where the Main Volume Descriptor
-  // Sequence starts. Therefore, we'll look for Logical Volume Descriptors and
-  // Partitions Descriptors and save them in memory, accordingly.
-  //
-  // Note also that each descriptor will be aligned on a block size (BlockSize)
-  // boundary, so we need to read one block at a time.
+  // Allocate buffer for reading disk blocks
   //
-  BlockSize    = BlockIo->Media->BlockSize;
-  ExtentAd     = &AnchorPoint->MainVolumeDescriptorSequenceExtent;
-  StartingLsn  = (UINT64)ExtentAd->ExtentLocation;
-  EndingLsn    = StartingLsn + DivU64x32 (
-                                     (UINT64)ExtentAd->ExtentLength,
-                                     BlockSize
-                                     );
-
-  Volume->LogicalVolDescs =
-    (UDF_LOGICAL_VOLUME_DESCRIPTOR **)AllocateZeroPool (ExtentAd->ExtentLength);
-  if (Volume->LogicalVolDescs == NULL) {
-    return EFI_OUT_OF_RESOURCES;
-  }
-
-  Volume->PartitionDescs =
-    (UDF_PARTITION_DESCRIPTOR **)AllocateZeroPool (ExtentAd->ExtentLength);
-  if (Volume->PartitionDescs == NULL) {
-    Status = EFI_OUT_OF_RESOURCES;
-    goto Error_Alloc_Pds;
-  }
-
-  Buffer = AllocateZeroPool (BlockSize);
+  Buffer = AllocateZeroPool ((UINTN)BlockSize);
   if (Buffer == NULL) {
-    Status = EFI_OUT_OF_RESOURCES;
-    goto Error_Alloc_Buf;
+    return EFI_OUT_OF_RESOURCES;
   }
 
-  Volume->LogicalVolDescsNo  = 0;
-  Volume->PartitionDescsNo   = 0;
-
-  while (StartingLsn <= EndingLsn) {
-    Status = DiskIo->ReadDisk (
-      DiskIo,
+  //
+  // The logical partition created by Partition driver is relative to the main
+  // VDS extent location, so we start the Main Volume Descriptor Sequence at
+  // LBA 0.
+  //
+  // We don't need to check again if we have valid Volume Descriptors here since
+  // Partition driver already did.
+  //
+  SeqStartBlock = 0;
+  SeqEndBlock = SeqStartBlock + DivU64x32 ((UINT64)ExtentAd->ExtentLength,
+                                           BlockSize);
+  StopSequence = FALSE;
+  for (; SeqStartBlock < SeqEndBlock && !StopSequence; SeqStartBlock++) {
+    //
+    // Read disk block
+    //
+    Status = BlockIo->ReadBlocks (
+      BlockIo,
       BlockIo->Media->MediaId,
-      MultU64x32 (StartingLsn, BlockSize),
+      SeqStartBlock,
       BlockSize,
       Buffer
       );
     if (EFI_ERROR (Status)) {
-      goto Error_Read_Disk_Blk;
+      goto Out_Free;
     }
 
-    if (IS_TD (Buffer)) {
+    DescriptorTag = Buffer;
+
+    switch (UDF_TAG_ID (DescriptorTag)) {
+    case UdfPartitionDescriptor:
       //
-      // Found a Terminating Descriptor. Stop the sequence then.
+      // Save Partition Descriptor
       //
+      CopyMem (&Volume->PartitionDesc, Buffer, sizeof (Volume->PartitionDesc));
       break;
-    }
 
-    if (IS_LVD (Buffer)) {
+    case UdfLogicalVolumeDescriptor:
       //
-      // Found a Logical Volume Descriptor.
+      // Save Logical Volume Descriptor
       //
-      LogicalVolDesc =
-        (UDF_LOGICAL_VOLUME_DESCRIPTOR *)
-        AllocateZeroPool (sizeof (UDF_LOGICAL_VOLUME_DESCRIPTOR));
-      if (LogicalVolDesc == NULL) {
-        Status = EFI_OUT_OF_RESOURCES;
-        goto Error_Alloc_Lvd;
-      }
+      CopyMem (&Volume->LogicalVolDesc, Buffer, sizeof (Volume->LogicalVolDesc));
+      break;
 
-      CopyMem ((VOID *)LogicalVolDesc, Buffer,
-               sizeof (UDF_LOGICAL_VOLUME_DESCRIPTOR));
-      Volume->LogicalVolDescs[Volume->LogicalVolDescsNo++] = LogicalVolDesc;
-    } else if (IS_PD (Buffer)) {
-      //
-      // Found a Partition Descriptor.
-      //
-      PartitionDesc =
-        (UDF_PARTITION_DESCRIPTOR *)
-        AllocateZeroPool (sizeof (UDF_PARTITION_DESCRIPTOR));
-      if (PartitionDesc == NULL) {
-        Status = EFI_OUT_OF_RESOURCES;
-        goto Error_Alloc_Pd;
-      }
+    case UdfTerminatingDescriptor:
+      StopSequence = TRUE;
+      break;
 
-      CopyMem ((VOID *)PartitionDesc, Buffer,
-               sizeof (UDF_PARTITION_DESCRIPTOR));
-      Volume->PartitionDescs[Volume->PartitionDescsNo++] = PartitionDesc;
+    default:
+      ;
     }
-
-    StartingLsn++;
   }
 
   //
-  // When an UDF volume (revision 2.00 or higher) contains a File Entry rather
-  // than an Extended File Entry (which is not recommended as per spec), we need
-  // to make sure the size of a FE will be _at least_ 2048
-  // (UDF_LOGICAL_SECTOR_SIZE) bytes long to keep backward compatibility.
+  // Determine FE (File Entry) size
   //
-  LogicalBlockSize = LV_BLOCK_SIZE (Volume, UDF_DEFAULT_LV_NUM);
+  LogicalBlockSize = Volume->LogicalVolDesc.LogicalBlockSize;
   if (LogicalBlockSize >= UDF_LOGICAL_SECTOR_SIZE) {
-    Volume->FileEntrySize = LogicalBlockSize;
+    Volume->FileEntrySize = (UINTN)LogicalBlockSize;
   } else {
     Volume->FileEntrySize = UDF_LOGICAL_SECTOR_SIZE;
   }
 
-  FreePool (Buffer);
+  Status = EFI_SUCCESS;
 
-  return EFI_SUCCESS;
-
-Error_Alloc_Pd:
-Error_Alloc_Lvd:
-  for (Index = 0; Index < Volume->PartitionDescsNo; Index++) {
-    FreePool ((VOID *)Volume->PartitionDescs[Index]);
-  }
-
-  for (Index = 0; Index < Volume->LogicalVolDescsNo; Index++) {
-    FreePool ((VOID *)Volume->LogicalVolDescs[Index]);
-  }
-
-Error_Read_Disk_Blk:
+Out_Free:
+  //
+  // Free block read buffer
+  //
   FreePool (Buffer);
 
-Error_Alloc_Buf:
-  FreePool ((VOID *)Volume->PartitionDescs);
-  Volume->PartitionDescs = NULL;
-
-Error_Alloc_Pds:
-  FreePool ((VOID *)Volume->LogicalVolDescs);
-  Volume->LogicalVolDescs = NULL;
-
   return Status;
 }
 
@@ -262,48 +216,53 @@ GetPdFromLongAd (
   )
 {
   UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;
-  UINTN                          Index;
-  UDF_PARTITION_DESCRIPTOR       *PartitionDesc;
   UINT16                         PartitionNum;
 
-  LogicalVolDesc = Volume->LogicalVolDescs[UDF_DEFAULT_LV_NUM];
+  LogicalVolDesc = &Volume->LogicalVolDesc;
 
-  switch (LV_UDF_REVISION (LogicalVolDesc)) {
+  switch (UDF_LVD_REVISION (LogicalVolDesc)) {
   case 0x0102:
+  case 0x0150:
+  case 0x0200:
+  case 0x0201:
+  case 0x0250:
+  case 0x0260:
     //
-    // As per UDF 1.02 specification:
+    // UDF 1.02 specification:
     //
     // There shall be exactly one prevailing Logical Volume Descriptor recorded
     // per Volume Set. The Partition Maps field shall contain only Type 1
     // Partition Maps.
     //
-    PartitionNum = *(UINT16 *)((UINTN)&LogicalVolDesc->PartitionMaps[4]);
-    break;
-  case 0x0150:
+    // UDF 1.50 through 2.60 specs say:
     //
-    // Ensure Type 1 Partition map. Other types aren't supported in this
-    // implementation.
+    // For the purpose of interchange partition maps shall be limited to
+    // Partition Map type 1, except type 2 maps as described in the document.
+    //
+    // NOTE: Only one Type 1 (Physical) Partition is supported. It has been
+    // checked already in Partition driver for existence of a single Type 1
+    // Partition map, so we don't have to double check here.
+    //
+    // Partition reference number can also be retrieved from
+    // LongAd->ExtentLocation.PartitionReferenceNumber, however the spec says
+    // it may be 0, so let's not rely on it.
     //
-    if (LogicalVolDesc->PartitionMaps[0] != 1 ||
-        LogicalVolDesc->PartitionMaps[1] != 6) {
-      return NULL;
-    }
     PartitionNum = *(UINT16 *)((UINTN)&LogicalVolDesc->PartitionMaps[4]);
     break;
-  case 0x0260:
+
+  default:
     //
-    // Fall through.
+    // Unsupported UDF revision
     //
-  default:
-    PartitionNum = LongAd->ExtentLocation.PartitionReferenceNumber;
-    break;
+    return NULL;
   }
 
-  for (Index = 0; Index < Volume->PartitionDescsNo; Index++) {
-    PartitionDesc = Volume->PartitionDescs[Index];
-    if (PartitionDesc->PartitionNumber == PartitionNum) {
-      return PartitionDesc;
-    }
+  //
+  // Check if partition number matches Partition Descriptor found in Main Volume
+  // Descriptor Sequence.
+  //
+  if (Volume->PartitionDesc.PartitionNumber == PartitionNum) {
+    return &Volume->PartitionDesc;
   }
 
   return NULL;
@@ -329,13 +288,15 @@ GetLongAdLsn (
   PartitionDesc = GetPdFromLongAd (Volume, LongAd);
   ASSERT (PartitionDesc != NULL);
 
-  return (UINT64)PartitionDesc->PartitionStartingLocation +
-                 LongAd->ExtentLocation.LogicalBlockNumber;
+  return (UINT64)PartitionDesc->PartitionStartingLocation -
+    Volume->MainVdsStartLocation +
+    LongAd->ExtentLocation.LogicalBlockNumber;
 }
 
 /**
   Return logical sector number of a given Short Allocation Descriptor.
 
+  @param[in]  Volume              Volume pointer.
   @param[in]  PartitionDesc       Partition Descriptor pointer.
   @param[in]  ShortAd             Short Allocation Descriptor pointer.
 
@@ -344,14 +305,13 @@ GetLongAdLsn (
 **/
 UINT64
 GetShortAdLsn (
+  IN UDF_VOLUME_INFO                  *Volume,
   IN UDF_PARTITION_DESCRIPTOR         *PartitionDesc,
   IN UDF_SHORT_ALLOCATION_DESCRIPTOR  *ShortAd
   )
 {
-  ASSERT (PartitionDesc != NULL);
-
-  return (UINT64)PartitionDesc->PartitionStartingLocation +
-    ShortAd->ExtentPosition;
+  return (UINT64)PartitionDesc->PartitionStartingLocation -
+    Volume->MainVdsStartLocation + ShortAd->ExtentPosition;
 }
 
 /**
@@ -363,8 +323,6 @@ GetShortAdLsn (
   @param[in]  BlockIo             BlockIo interface.
   @param[in]  DiskIo              DiskIo interface.
   @param[in]  Volume              Volume information pointer.
-  @param[in]  LogicalVolDescNum   Index of Logical Volume Descriptor
-  @param[out] FileSetDesc         File Set Descriptor pointer.
 
   @retval EFI_SUCCESS             File Set Descriptor pointer found.
   @retval EFI_VOLUME_CORRUPTED    The file system structures are corrupted.
@@ -375,36 +333,42 @@ EFI_STATUS
 FindFileSetDescriptor (
   IN   EFI_BLOCK_IO_PROTOCOL    *BlockIo,
   IN   EFI_DISK_IO_PROTOCOL     *DiskIo,
-  IN   UDF_VOLUME_INFO          *Volume,
-  IN   UINTN                    LogicalVolDescNum,
-  OUT  UDF_FILE_SET_DESCRIPTOR  *FileSetDesc
+  IN   UDF_VOLUME_INFO          *Volume
   )
 {
   EFI_STATUS                     Status;
   UINT64                         Lsn;
   UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;
+  UDF_DESCRIPTOR_TAG             *DescriptorTag;
 
-  LogicalVolDesc = Volume->LogicalVolDescs[LogicalVolDescNum];
+  LogicalVolDesc = &Volume->LogicalVolDesc;
   Lsn = GetLongAdLsn (Volume, &LogicalVolDesc->LogicalVolumeContentsUse);
 
   //
-  // Read extent (Long Ad).
+  // As per UDF 2.60 specification:
+  //
+  // There shall be exactly one File Set Descriptor recorded per Logical
+  // Volume.
+  //
+  // Read disk block
   //
   Status = DiskIo->ReadDisk (
     DiskIo,
     BlockIo->Media->MediaId,
     MultU64x32 (Lsn, LogicalVolDesc->LogicalBlockSize),
-    sizeof (UDF_FILE_SET_DESCRIPTOR),
-    (VOID *)FileSetDesc
+    sizeof (Volume->FileSetDesc),
+    &Volume->FileSetDesc
     );
   if (EFI_ERROR (Status)) {
     return Status;
   }
 
+  DescriptorTag = &Volume->FileSetDesc.DescriptorTag;
+
   //
-  // Check if the read extent contains a valid FSD's tag identifier.
+  // Check if read block is a File Set Descriptor
   //
-  if (!IS_FSD (FileSetDesc)) {
+  if (UDF_TAG_ID (DescriptorTag) != UdfFileSetDescriptor) {
     return EFI_VOLUME_CORRUPTED;
   }
 
@@ -412,82 +376,6 @@ FindFileSetDescriptor (
 }
 
 /**
-  Get all File Set Descriptors for each Logical Volume Descriptor.
-
-  @param[in]      BlockIo         BlockIo interface.
-  @param[in]      DiskIo          DiskIo interface.
-  @param[in, out] Volume          Volume information pointer.
-
-  @retval EFI_SUCCESS             File Set Descriptors were got.
-  @retval EFI_OUT_OF_RESOURCES    File Set Descriptors were not got due to lack
-                                  of resources.
-  @retval other                   Error occured when finding File Set
-                                  Descriptor in Logical Volume Descriptor.
-
-**/
-EFI_STATUS
-GetFileSetDescriptors (
-  IN      EFI_BLOCK_IO_PROTOCOL  *BlockIo,
-  IN      EFI_DISK_IO_PROTOCOL   *DiskIo,
-  IN OUT  UDF_VOLUME_INFO        *Volume
-  )
-{
-  EFI_STATUS               Status;
-  UINTN                    Index;
-  UDF_FILE_SET_DESCRIPTOR  *FileSetDesc;
-  UINTN                    Count;
-
-  Volume->FileSetDescs =
-    (UDF_FILE_SET_DESCRIPTOR **)AllocateZeroPool (
-      Volume->LogicalVolDescsNo * sizeof (UDF_FILE_SET_DESCRIPTOR));
-  if (Volume->FileSetDescs == NULL) {
-    return EFI_OUT_OF_RESOURCES;
-  }
-
-  for (Index = 0; Index < Volume->LogicalVolDescsNo; Index++) {
-    FileSetDesc = AllocateZeroPool (sizeof (UDF_FILE_SET_DESCRIPTOR));
-    if (FileSetDesc == NULL) {
-      Status = EFI_OUT_OF_RESOURCES;
-      goto Error_Alloc_Fsd;
-    }
-
-    //
-    // Find a FSD for this LVD.
-    //
-    Status = FindFileSetDescriptor (
-      BlockIo,
-      DiskIo,
-      Volume,
-      Index,
-      FileSetDesc
-      );
-    if (EFI_ERROR (Status)) {
-      goto Error_Find_Fsd;
-    }
-
-    //
-    // Got one. Save it.
-    //
-    Volume->FileSetDescs[Index] = FileSetDesc;
-  }
-
-  Volume->FileSetDescsNo = Volume->LogicalVolDescsNo;
-  return EFI_SUCCESS;
-
-Error_Find_Fsd:
-  Count = Index + 1;
-  for (Index = 0; Index < Count; Index++) {
-    FreePool ((VOID *)Volume->FileSetDescs[Index]);
-  }
-
-  FreePool ((VOID *)Volume->FileSetDescs);
-  Volume->FileSetDescs = NULL;
-
-Error_Alloc_Fsd:
-  return Status;
-}
-
-/**
   Read Volume and File Structure on an UDF file system.
 
   @param[in]   BlockIo            BlockIo interface.
@@ -507,9 +395,10 @@ ReadVolumeFileStructure (
 {
   EFI_STATUS                            Status;
   UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  AnchorPoint;
+  UDF_EXTENT_AD                         *ExtentAd;
 
   //
-  // Find an AVDP.
+  // Find Anchor Volume Descriptor Pointer
   //
   Status = FindAnchorVolumeDescriptorPointer (
     BlockIo,
@@ -521,7 +410,14 @@ ReadVolumeFileStructure (
   }
 
   //
-  // AVDP has been found. Start MVDS.
+  // Save Main VDS start block number
+  //
+  ExtentAd = &AnchorPoint.MainVolumeDescriptorSequenceExtent;
+
+  Volume->MainVdsStartLocation = (UINT64)ExtentAd->ExtentLocation;
+
+  //
+  // Start Main Volume Descriptor Sequence.
   //
   Status = StartMainVolumeDescriptorSequence (
     BlockIo,
@@ -620,16 +516,19 @@ GetFileEntryData (
   OUT  UINT64  *Length
   )
 {
+  UDF_DESCRIPTOR_TAG       *DescriptorTag;
   UDF_EXTENDED_FILE_ENTRY  *ExtendedFileEntry;
   UDF_FILE_ENTRY           *FileEntry;
 
-  if (IS_EFE (FileEntryData)) {
+  DescriptorTag = FileEntryData;
+
+  if (UDF_TAG_ID (DescriptorTag) == UdfExtendedFileEntry) {
     ExtendedFileEntry = (UDF_EXTENDED_FILE_ENTRY *)FileEntryData;
 
     *Length  = ExtendedFileEntry->InformationLength;
     *Data    = (VOID *)((UINT8 *)ExtendedFileEntry->Data +
                         ExtendedFileEntry->LengthOfExtendedAttributes);
-  } else if (IS_FE (FileEntryData)) {
+  } else if (UDF_TAG_ID (DescriptorTag) == UdfFileEntry) {
     FileEntry = (UDF_FILE_ENTRY *)FileEntryData;
 
     *Length  = FileEntry->InformationLength;
@@ -654,16 +553,19 @@ GetAdsInformation (
   OUT  UINT64  *Length
   )
 {
+  UDF_DESCRIPTOR_TAG       *DescriptorTag;
   UDF_EXTENDED_FILE_ENTRY  *ExtendedFileEntry;
   UDF_FILE_ENTRY           *FileEntry;
 
-  if (IS_EFE (FileEntryData)) {
+  DescriptorTag = FileEntryData;
+
+  if (UDF_TAG_ID (DescriptorTag) == UdfExtendedFileEntry) {
     ExtendedFileEntry = (UDF_EXTENDED_FILE_ENTRY *)FileEntryData;
 
     *Length = ExtendedFileEntry->LengthOfAllocationDescriptors;
     *AdsData = (VOID *)((UINT8 *)ExtendedFileEntry->Data +
                         ExtendedFileEntry->LengthOfExtendedAttributes);
-  } else if (IS_FE (FileEntryData)) {
+  } else if (UDF_TAG_ID (DescriptorTag) == UdfFileEntry) {
     FileEntry = (UDF_FILE_ENTRY *)FileEntryData;
 
     *Length = FileEntry->LengthOfAllocationDescriptors;
@@ -850,6 +752,7 @@ GetAllocationDescriptorLsn (
     return GetLongAdLsn (Volume, (UDF_LONG_ALLOCATION_DESCRIPTOR *)Ad);
   } else if (RecordingFlags == ShortAdsSequence) {
     return GetShortAdLsn (
+      Volume,
       GetPdFromLongAd (Volume, ParentIcb),
       (UDF_SHORT_ALLOCATION_DESCRIPTOR *)Ad
       );
@@ -897,6 +800,7 @@ GetAedAdsOffset (
   VOID                              *Data;
   UINT32                            LogicalBlockSize;
   UDF_ALLOCATION_EXTENT_DESCRIPTOR  *AllocExtDesc;
+  UDF_DESCRIPTOR_TAG                *DescriptorTag;
 
   ExtentLength  = GET_EXTENT_LENGTH (RecordingFlags, Ad);
   Lsn           = GetAllocationDescriptorLsn (RecordingFlags,
@@ -909,7 +813,7 @@ GetAedAdsOffset (
     return EFI_OUT_OF_RESOURCES;
   }
 
-  LogicalBlockSize = LV_BLOCK_SIZE (Volume, UDF_DEFAULT_LV_NUM);
+  LogicalBlockSize = Volume->LogicalVolDesc.LogicalBlockSize;
 
   //
   // Read extent.
@@ -925,11 +829,14 @@ GetAedAdsOffset (
     goto Exit;
   }
 
+  AllocExtDesc = (UDF_ALLOCATION_EXTENT_DESCRIPTOR *)Data;
+
+  DescriptorTag = &AllocExtDesc->DescriptorTag;
+
   //
   // Check if read extent contains a valid tag identifier for AED.
   //
-  AllocExtDesc = (UDF_ALLOCATION_EXTENT_DESCRIPTOR *)Data;
-  if (!IS_AED (AllocExtDesc)) {
+  if (UDF_TAG_ID (DescriptorTag) != UdfAllocationExtentDescriptor) {
     Status = EFI_VOLUME_CORRUPTED;
     goto Exit;
   }
@@ -1102,7 +1009,7 @@ ReadFile (
   UINT32                  ExtentLength;
   UDF_FE_RECORDING_FLAGS  RecordingFlags;
 
-  LogicalBlockSize  = LV_BLOCK_SIZE (Volume, UDF_DEFAULT_LV_NUM);
+  LogicalBlockSize  = Volume->LogicalVolDesc.LogicalBlockSize;
   DoFreeAed         = FALSE;
 
   //
@@ -1444,7 +1351,7 @@ InternalFindFile (
   //
   // Check if parent file is really directory.
   //
-  if (!IS_FE_DIRECTORY (Parent->FileEntry)) {
+  if (FE_ICB_FILE_TYPE (Parent->FileEntry) != UdfFileEntryDirectory) {
     return EFI_NOT_FOUND;
   }
 
@@ -1489,7 +1396,7 @@ InternalFindFile (
       break;
     }
 
-    if (IS_FID_PARENT_FILE (FileIdentifierDesc)) {
+    if (FileIdentifierDesc->FileCharacteristics & PARENT_FILE) {
       //
       // This FID contains the location (FE/EFE) of the parent directory of this
       // directory (Parent), and if FileName is either ".." or "\\", then it's
@@ -1592,6 +1499,9 @@ ReadUdfVolumeInformation (
 {
   EFI_STATUS Status;
 
+  //
+  // Read all necessary UDF volume information and keep it private to the driver
+  //
   Status = ReadVolumeFileStructure (
     BlockIo,
     DiskIo,
@@ -1601,13 +1511,12 @@ ReadUdfVolumeInformation (
     return Status;
   }
 
-  Status = GetFileSetDescriptors (
-    BlockIo,
-    DiskIo,
-    Volume
-    );
+  //
+  // Find File Set Descriptor
+  //
+  Status = FindFileSetDescriptor (BlockIo, DiskIo, Volume);
   if (EFI_ERROR (Status)) {
-    CleanupVolumeInformation (Volume);
+    return Status;
   }
 
   return Status;
@@ -1644,7 +1553,7 @@ FindRootDirectory (
     BlockIo,
     DiskIo,
     Volume,
-    &Volume->FileSetDescs[0]->RootDirectoryIcb,
+    &Volume->FileSetDesc.RootDirectoryIcb,
     &File->FileEntry
     );
   if (EFI_ERROR (Status)) {
@@ -1661,7 +1570,7 @@ FindRootDirectory (
     L"\\",
     NULL,
     &Parent,
-    &Volume->FileSetDescs[0]->RootDirectoryIcb,
+    &Volume->FileSetDesc.RootDirectoryIcb,
     File
     );
   if (EFI_ERROR (Status)) {
@@ -1697,12 +1606,13 @@ FindFileEntry (
   OUT  VOID                            **FileEntry
   )
 {
-  EFI_STATUS  Status;
-  UINT64      Lsn;
-  UINT32      LogicalBlockSize;
+  EFI_STATUS          Status;
+  UINT64              Lsn;
+  UINT32              LogicalBlockSize;
+  UDF_DESCRIPTOR_TAG  *DescriptorTag;
 
   Lsn               = GetLongAdLsn (Volume, Icb);
-  LogicalBlockSize  = LV_BLOCK_SIZE (Volume, UDF_DEFAULT_LV_NUM);
+  LogicalBlockSize  = Volume->LogicalVolDesc.LogicalBlockSize;
 
   *FileEntry = AllocateZeroPool (Volume->FileEntrySize);
   if (*FileEntry == NULL) {
@@ -1723,11 +1633,14 @@ FindFileEntry (
     goto Error_Read_Disk_Blk;
   }
 
+  DescriptorTag = *FileEntry;
+
   //
   // Check if the read extent contains a valid Tag Identifier for the expected
   // FE/EFE.
   //
-  if (!IS_FE (*FileEntry) && !IS_EFE (*FileEntry)) {
+  if (UDF_TAG_ID (DescriptorTag) != UdfFileEntry &&
+      UDF_TAG_ID (DescriptorTag) != UdfExtendedFileEntry) {
     Status = EFI_VOLUME_CORRUPTED;
     goto Error_Invalid_Fe;
   }
@@ -1837,7 +1750,7 @@ FindFile (
     // If the found file is a symlink, then find its respective FE/EFE and
     // FID descriptors.
     //
-    if (IS_FE_SYMLINK (File->FileEntry)) {
+    if (FE_ICB_FILE_TYPE (File->FileEntry) == UdfFileEntrySymlink) {
       FreePool ((VOID *)File->FileIdentifierDesc);
 
       FileEntry = File->FileEntry;
@@ -1951,7 +1864,7 @@ ReadDirectoryEntry (
     // Update FidOffset to point to next FID.
     //
     ReadDirInfo->FidOffset += GetFidDescriptorLength (FileIdentifierDesc);
-  } while (IS_FID_DELETED_FILE (FileIdentifierDesc));
+  } while (FileIdentifierDesc->FileCharacteristics & DELETED_FILE);
 
   DuplicateFid (FileIdentifierDesc, FoundFid);
 
@@ -2197,43 +2110,6 @@ Error_Find_File:
 }
 
 /**
-  Clean up in-memory UDF volume information.
-
-  @param[in] Volume Volume information pointer.
-
-**/
-VOID
-CleanupVolumeInformation (
-  IN UDF_VOLUME_INFO *Volume
-  )
-{
-  UINTN Index;
-
-  if (Volume->LogicalVolDescs != NULL) {
-    for (Index = 0; Index < Volume->LogicalVolDescsNo; Index++) {
-      FreePool ((VOID *)Volume->LogicalVolDescs[Index]);
-    }
-    FreePool ((VOID *)Volume->LogicalVolDescs);
-  }
-
-  if (Volume->PartitionDescs != NULL) {
-    for (Index = 0; Index < Volume->PartitionDescsNo; Index++) {
-      FreePool ((VOID *)Volume->PartitionDescs[Index]);
-    }
-    FreePool ((VOID *)Volume->PartitionDescs);
-  }
-
-  if (Volume->FileSetDescs != NULL) {
-    for (Index = 0; Index < Volume->FileSetDescsNo; Index++) {
-      FreePool ((VOID *)Volume->FileSetDescs[Index]);
-    }
-    FreePool ((VOID *)Volume->FileSetDescs);
-  }
-
-  ZeroMem ((VOID *)Volume, sizeof (UDF_VOLUME_INFO));
-}
-
-/**
   Clean up in-memory UDF file information.
 
   @param[in] File File information pointer.
@@ -2333,6 +2209,7 @@ SetFileInfo (
   EFI_FILE_INFO            *FileInfo;
   UDF_FILE_ENTRY           *FileEntry;
   UDF_EXTENDED_FILE_ENTRY  *ExtendedFileEntry;
+  UDF_DESCRIPTOR_TAG       *DescriptorTag;
 
   //
   // Calculate the needed size for the EFI_FILE_INFO structure.
@@ -2367,7 +2244,9 @@ SetFileInfo (
     FileInfo->Attribute |= EFI_FILE_HIDDEN;
   }
 
-  if (IS_FE (File->FileEntry)) {
+  DescriptorTag = File->FileEntry;
+
+  if (UDF_TAG_ID (DescriptorTag) == UdfFileEntry) {
     FileEntry = (UDF_FILE_ENTRY *)File->FileEntry;
 
     //
@@ -2403,7 +2282,7 @@ SetFileInfo (
                                    FileEntry->AccessTime.Second;
     FileInfo->LastAccessTime.Nanosecond  =
                                    FileEntry->AccessTime.HundredsOfMicroseconds;
-  } else if (IS_EFE (File->FileEntry)) {
+  } else if (UDF_TAG_ID (DescriptorTag) == UdfExtendedFileEntry) {
     ExtendedFileEntry = (UDF_EXTENDED_FILE_ENTRY *)File->FileEntry;
 
     //
@@ -2487,91 +2366,103 @@ GetVolumeSize (
   OUT  UINT64                 *FreeSpaceSize
   )
 {
-  UDF_EXTENT_AD                 ExtentAd;
-  UINT32                        LogicalBlockSize;
-  UINT64                        Lsn;
-  EFI_STATUS                    Status;
-  UDF_LOGICAL_VOLUME_INTEGRITY  *LogicalVolInt;
-  UINTN                         Index;
-  UINTN                         Length;
-  UINT32                        LsnsNo;
-
-  *VolumeSize     = 0;
-  *FreeSpaceSize  = 0;
-
-  for (Index = 0; Index < Volume->LogicalVolDescsNo; Index++) {
-    CopyMem ((VOID *)&ExtentAd,
-             (VOID *)&Volume->LogicalVolDescs[Index]->IntegritySequenceExtent,
-             sizeof (UDF_EXTENT_AD));
-    if (ExtentAd.ExtentLength == 0) {
-      continue;
-    }
+  EFI_STATUS                     Status;
+  UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;
+  UDF_EXTENT_AD                  *ExtentAd;
+  UINT64                         Lsn;
+  UINT32                         LogicalBlockSize;
+  UDF_LOGICAL_VOLUME_INTEGRITY   *LogicalVolInt;
+  UDF_DESCRIPTOR_TAG             *DescriptorTag;
+  UINTN                          Index;
+  UINTN                          Length;
+  UINT32                         LsnsNo;
 
-    LogicalBlockSize = LV_BLOCK_SIZE (Volume, Index);
+  LogicalVolDesc = &Volume->LogicalVolDesc;
 
-  Read_Next_Sequence:
-    LogicalVolInt = (UDF_LOGICAL_VOLUME_INTEGRITY *)
-      AllocatePool (ExtentAd.ExtentLength);
-    if (LogicalVolInt == NULL) {
-      return EFI_OUT_OF_RESOURCES;
-    }
+  ExtentAd = &LogicalVolDesc->IntegritySequenceExtent;
+
+  if (ExtentAd->ExtentLength == 0) {
+    return EFI_VOLUME_CORRUPTED;
+  }
 
-    Lsn = (UINT64)ExtentAd.ExtentLocation;
+  LogicalVolInt = AllocatePool (ExtentAd->ExtentLength);
+  if (LogicalVolInt == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
 
-    Status = DiskIo->ReadDisk (
-      DiskIo,
-      BlockIo->Media->MediaId,
-      MultU64x32 (Lsn, LogicalBlockSize),
-      ExtentAd.ExtentLength,
-      (VOID *)LogicalVolInt
-      );
-    if (EFI_ERROR (Status)) {
-      FreePool ((VOID *)LogicalVolInt);
-      return Status;
-    }
+  //
+  // Get location of Logical Volume Integrity Descriptor
+  //
+  Lsn = (UINT64)ExtentAd->ExtentLocation - Volume->MainVdsStartLocation;
 
-    if (!IS_LVID (LogicalVolInt)) {
-      FreePool ((VOID *)LogicalVolInt);
-      return EFI_VOLUME_CORRUPTED;
-    }
+  LogicalBlockSize = LogicalVolDesc->LogicalBlockSize;
 
-    Length = LogicalVolInt->NumberOfPartitions;
-    for (Index = 0; Index < Length; Index += sizeof (UINT32)) {
-      LsnsNo = *(UINT32 *)((UINT8 *)LogicalVolInt->Data + Index);
-      if (LsnsNo == 0xFFFFFFFFUL) {
-        //
-        // Size not specified.
-        //
-        continue;
-      }
+  //
+  // Read disk block
+  //
+  Status = DiskIo->ReadDisk (
+    DiskIo,
+    BlockIo->Media->MediaId,
+    MultU64x32 (Lsn, LogicalBlockSize),
+    ExtentAd->ExtentLength,
+    LogicalVolInt
+    );
+  if (EFI_ERROR (Status)) {
+    goto Out_Free;
+  }
 
-      *FreeSpaceSize += MultU64x32 ((UINT64)LsnsNo, LogicalBlockSize);
-    }
+  DescriptorTag = &LogicalVolInt->DescriptorTag;
 
-    Length = (LogicalVolInt->NumberOfPartitions * sizeof (UINT32)) << 1;
-    for (; Index < Length; Index += sizeof (UINT32)) {
-      LsnsNo = *(UINT32 *)((UINT8 *)LogicalVolInt->Data + Index);
-      if (LsnsNo == 0xFFFFFFFFUL) {
-        //
-        // Size not specified.
-        //
-        continue;
-      }
+  //
+  // Check if read block is a Logical Volume Integrity Descriptor
+  //
+  if (UDF_TAG_ID (DescriptorTag) != UdfLogicalVolumeIntegrityDescriptor) {
+    Status = EFI_VOLUME_CORRUPTED;
+    goto Out_Free;
+  }
 
-      *VolumeSize += MultU64x32 ((UINT64)LsnsNo, LogicalBlockSize);
-    }
+  *VolumeSize = 0;
+  *FreeSpaceSize = 0;
 
-    CopyMem ((VOID *)&ExtentAd,(VOID *)&LogicalVolInt->NextIntegrityExtent,
-             sizeof (UDF_EXTENT_AD));
-    if (ExtentAd.ExtentLength > 0) {
-      FreePool ((VOID *)LogicalVolInt);
-      goto Read_Next_Sequence;
+  Length = LogicalVolInt->NumberOfPartitions;
+  for (Index = 0; Index < Length; Index += sizeof (UINT32)) {
+    LsnsNo = *(UINT32 *)((UINT8 *)LogicalVolInt->Data + Index);
+    //
+    // Check if size is not specified
+    //
+    if (LsnsNo == 0xFFFFFFFFUL) {
+      continue;
     }
+    //
+    // Accumulate free space size
+    //
+    *FreeSpaceSize += MultU64x32 ((UINT64)LsnsNo, LogicalBlockSize);
+  }
 
-    FreePool ((VOID *)LogicalVolInt);
+  Length = LogicalVolInt->NumberOfPartitions * sizeof (UINT32) * 2;
+  for (; Index < Length; Index += sizeof (UINT32)) {
+    LsnsNo = *(UINT32 *)((UINT8 *)LogicalVolInt->Data + Index);
+    //
+    // Check if size is not specified
+    //
+    if (LsnsNo == 0xFFFFFFFFUL) {
+      continue;
+    }
+    //
+    // Accumulate used volume space
+    //
+    *VolumeSize += MultU64x32 ((UINT64)LsnsNo, LogicalBlockSize);
   }
 
-  return EFI_SUCCESS;
+  Status = EFI_SUCCESS;
+
+Out_Free:
+  //
+  // Free Logical Volume Integrity Descriptor
+  //
+  FreePool (LogicalVolInt);
+
+  return Status;
 }
 
 /**
diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/Udf.c b/MdeModulePkg/Universal/Disk/UdfDxe/Udf.c
index 49dc7077b7..d4163b89ca 100644
--- a/MdeModulePkg/Universal/Disk/UdfDxe/Udf.c
+++ b/MdeModulePkg/Universal/Disk/UdfDxe/Udf.c
@@ -276,13 +276,6 @@ UdfDriverBindingStop (
       NULL
       );
 
-    //
-    // Check if there's any open file. If so, clean them up.
-    //
-    if (PrivFsData->OpenFiles > 0) {
-      CleanupVolumeInformation (&PrivFsData->Volume);
-    }
-
     FreePool ((VOID *)PrivFsData);
   }
 
diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/Udf.h b/MdeModulePkg/Universal/Disk/UdfDxe/Udf.h
index 44c843fd4d..ef2a3359ce 100644
--- a/MdeModulePkg/Universal/Disk/UdfDxe/Udf.h
+++ b/MdeModulePkg/Universal/Disk/UdfDxe/Udf.h
@@ -49,61 +49,34 @@
     { 0x89, 0x56, 0x73, 0xCD, 0xA3, 0x26, 0xCD, 0x0A }  \
   }
 
-#define UDF_DEFAULT_LV_NUM 0
-
-#define IS_PVD(_Pointer) \
-  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 1))
-#define IS_PD(_Pointer) \
-  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 5))
-#define IS_LVD(_Pointer) \
-  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 6))
-#define IS_TD(_Pointer) \
-  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 8))
-#define IS_FSD(_Pointer) \
-  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 256))
-#define IS_FE(_Pointer) \
-  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 261))
-#define IS_EFE(_Pointer) \
-  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 266))
-#define IS_FID(_Pointer) \
-  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 257))
-#define IS_AED(_Pointer) \
-  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 258))
-#define IS_LVID(_Pointer) \
-  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 9))
-
-#define _GET_FILETYPE(_Pointer) \
-  (IS_FE (_Pointer) ? \
-   (((UDF_FILE_ENTRY *)(_Pointer))->IcbTag.FileType) \
-   : \
-   (((UDF_EXTENDED_FILE_ENTRY *)(_Pointer))->IcbTag.FileType))
-
-#define IS_FE_DIRECTORY(_Pointer) \
-  ((BOOLEAN)(_GET_FILETYPE (_Pointer) == 4))
-#define IS_FE_STANDARD_FILE(_Pointer) \
-  ((BOOLEAN)(_GET_FILETYPE (_Pointer) == 5))
-#define IS_FE_SYMLINK(_Pointer) \
-  ((BOOLEAN)(_GET_FILETYPE (_Pointer) == 12))
+#define FE_ICB_FILE_TYPE(_Ptr) \
+  (UDF_FILE_ENTRY_TYPE)( \
+  (UDF_TAG_ID ((UDF_DESCRIPTOR_TAG *)(_Ptr)) == UdfFileEntry ? \
+   ((UDF_FILE_ENTRY *)(_Ptr))->IcbTag.FileType : \
+   ((UDF_EXTENDED_FILE_ENTRY *)(_Ptr))->IcbTag.FileType))
+
+typedef enum {
+  UdfFileEntryDirectory = 4,
+  UdfFileEntryStandardFile = 5,
+  UdfFileEntrySymlink = 12,
+} UDF_FILE_ENTRY_TYPE;
 
 #define HIDDEN_FILE     (1 << 0)
 #define DIRECTORY_FILE  (1 << 1)
 #define DELETED_FILE    (1 << 2)
 #define PARENT_FILE     (1 << 3)
 
-#define _GET_FILE_CHARS(_Pointer) \
-  (((UDF_FILE_IDENTIFIER_DESCRIPTOR *)(_Pointer))->FileCharacteristics)
-
-#define IS_FID_HIDDEN_FILE(_Pointer) \
-  ((BOOLEAN)(_GET_FILE_CHARS (_Pointer) & HIDDEN_FILE))
-#define IS_FID_DIRECTORY_FILE(_Pointer) \
-  ((BOOLEAN)(_GET_FILE_CHARS (_Pointer) & DIRECTORY_FILE))
-#define IS_FID_DELETED_FILE(_Pointer) \
-  ((BOOLEAN)(_GET_FILE_CHARS (_Pointer) & DELETED_FILE))
-#define IS_FID_PARENT_FILE(_Pointer) \
-  ((BOOLEAN)(_GET_FILE_CHARS (_Pointer) & PARENT_FILE))
-#define IS_FID_NORMAL_FILE(_Pointer) \
-  ((BOOLEAN)(!IS_FID_DIRECTORY_FILE (_Pointer) && \
-         !IS_FID_PARENT_FILE (_Pointer)))
+#define IS_FID_HIDDEN_FILE(_Fid) \
+  (BOOLEAN)((_Fid)->FileCharacteristics & HIDDEN_FILE)
+#define IS_FID_DIRECTORY_FILE(_Fid) \
+  (BOOLEAN)((_Fid)->FileCharacteristics & DIRECTORY_FILE)
+#define IS_FID_DELETED_FILE(_Fid) \
+  (BOOLEAN)((_Fid)->FileCharacteristics & DELETED_FILE)
+#define IS_FID_PARENT_FILE(_Fid) \
+  (BOOLEAN)((_Fid)->FileCharacteristics & PARENT_FILE)
+#define IS_FID_NORMAL_FILE(_Fid) \
+  (BOOLEAN)(!IS_FID_DIRECTORY_FILE (_Fid) && \
+            !IS_FID_PARENT_FILE (_Fid))
 
 typedef enum {
   ShortAdsSequence,
@@ -152,14 +125,8 @@ typedef enum {
 #define IS_VALID_COMPRESSION_ID(_CompId) \
   ((BOOLEAN)((_CompId) == 8 || (_CompId) == 16))
 
-#define LV_BLOCK_SIZE(_Vol, _LvNum) \
-  (_Vol)->LogicalVolDescs[(_LvNum)]->LogicalBlockSize
-
 #define UDF_STANDARD_IDENTIFIER_LENGTH   5
 
-#define LV_UDF_REVISION(_Lv) \
-  *(UINT16 *)(UINTN)(_Lv)->DomainIdentifier.IdentifierSuffix
-
 #pragma pack(1)
 
 typedef struct {
@@ -186,17 +153,6 @@ typedef struct {
 #pragma pack(1)
 
 typedef struct {
-  UINT8           CharacterSetType;
-  UINT8           CharacterSetInfo[63];
-} UDF_CHAR_SPEC;
-
-typedef struct {
-  UINT8           Flags;
-  UINT8           Identifier[23];
-  UINT8           IdentifierSuffix[8];
-} UDF_ENTITY_ID;
-
-typedef struct {
   UINT16          TypeAndTimezone;
   INT16           Year;
   UINT8           Month;
@@ -210,17 +166,6 @@ typedef struct {
 } UDF_TIMESTAMP;
 
 typedef struct {
-  UINT32        LogicalBlockNumber;
-  UINT16        PartitionReferenceNumber;
-} UDF_LB_ADDR;
-
-typedef struct {
-  UINT32                           ExtentLength;
-  UDF_LB_ADDR                      ExtentLocation;
-  UINT8                            ImplementationUse[6];
-} UDF_LONG_ALLOCATION_DESCRIPTOR;
-
-typedef struct {
   UDF_DESCRIPTOR_TAG                 DescriptorTag;
   UINT32                             PrevAllocationExtentDescriptor;
   UINT32                             LengthOfAllocationDescriptors;
@@ -235,6 +180,17 @@ typedef struct {
 } UDF_VOLUME_DESCRIPTOR;
 
 typedef struct {
+  UDF_DESCRIPTOR_TAG             DescriptorTag;
+  UDF_TIMESTAMP                  RecordingDateTime;
+  UINT32                         IntegrityType;
+  UDF_EXTENT_AD                  NextIntegrityExtent;
+  UINT8                          LogicalVolumeContentsUse[32];
+  UINT32                         NumberOfPartitions;
+  UINT32                         LengthOfImplementationUse;
+  UINT8                          Data[0];
+} UDF_LOGICAL_VOLUME_INTEGRITY;
+
+typedef struct {
   UDF_DESCRIPTOR_TAG         DescriptorTag;
   UINT32                     VolumeDescriptorSequenceNumber;
   UINT16                     PartitionFlags;
@@ -251,33 +207,6 @@ typedef struct {
 
 typedef struct {
   UDF_DESCRIPTOR_TAG              DescriptorTag;
-  UINT32                          VolumeDescriptorSequenceNumber;
-  UDF_CHAR_SPEC                   DescriptorCharacterSet;
-  UINT8                           LogicalVolumeIdentifier[128];
-  UINT32                          LogicalBlockSize;
-  UDF_ENTITY_ID                   DomainIdentifier;
-  UDF_LONG_ALLOCATION_DESCRIPTOR  LogicalVolumeContentsUse;
-  UINT32                          MapTableLength;
-  UINT32                          NumberOfPartitionMaps;
-  UDF_ENTITY_ID                   ImplementationIdentifier;
-  UINT8                           ImplementationUse[128];
-  UDF_EXTENT_AD                   IntegritySequenceExtent;
-  UINT8                           PartitionMaps[6];
-} UDF_LOGICAL_VOLUME_DESCRIPTOR;
-
-typedef struct {
-  UDF_DESCRIPTOR_TAG             DescriptorTag;
-  UDF_TIMESTAMP                  RecordingDateTime;
-  UINT32                         IntegrityType;
-  UDF_EXTENT_AD                  NextIntegrityExtent;
-  UINT8                          LogicalVolumeContentsUse[32];
-  UINT32                         NumberOfPartitions;
-  UINT32                         LengthOfImplementationUse;
-  UINT8                          Data[0];
-} UDF_LOGICAL_VOLUME_INTEGRITY;
-
-typedef struct {
-  UDF_DESCRIPTOR_TAG              DescriptorTag;
   UDF_TIMESTAMP                   RecordingDateAndTime;
   UINT16                          InterchangeLevel;
   UINT16                          MaximumInterchangeLevel;
@@ -389,12 +318,10 @@ typedef struct {
 // UDF filesystem driver's private data
 //
 typedef struct {
-  UDF_LOGICAL_VOLUME_DESCRIPTOR  **LogicalVolDescs;
-  UINTN                          LogicalVolDescsNo;
-  UDF_PARTITION_DESCRIPTOR       **PartitionDescs;
-  UINTN                          PartitionDescsNo;
-  UDF_FILE_SET_DESCRIPTOR        **FileSetDescs;
-  UINTN                          FileSetDescsNo;
+  UINT64                         MainVdsStartLocation;
+  UDF_LOGICAL_VOLUME_DESCRIPTOR  LogicalVolDesc;
+  UDF_PARTITION_DESCRIPTOR       PartitionDesc;
+  UDF_FILE_SET_DESCRIPTOR        FileSetDesc;
   UINTN                          FileEntrySize;
 } UDF_VOLUME_INFO;
 
@@ -884,17 +811,6 @@ ResolveSymlink (
   );
 
 /**
-  Clean up in-memory UDF volume information.
-
-  @param[in] Volume Volume information pointer.
-
-**/
-VOID
-CleanupVolumeInformation (
-  IN UDF_VOLUME_INFO *Volume
-  );
-
-/**
   Clean up in-memory UDF file information.
 
   @param[in] File File information pointer.
-- 
2.11.0

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Re: [edk2] [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix creation of UDF logical partition
Posted by Wu, Hao A 7 years, 3 months ago
I did a simple test on a Windows8.1 installation DVD, and here's the result
of a map command under shell:

Before the patch:
Mapping table
      FS0: Alias(s):CD0f65535a1:;BLK2:
          PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x5,0xFFFF,0x0)/CDROM(0x1)
     BLK0: Alias(s):
          PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x5,0xFFFF,0x0)
     BLK1: Alias(s):
          PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x5,0xFFFF,0x0)/CDROM(0x0)
      FS1: Alias(s):CD0f65535ab:;BLK5:
          PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x5,0xFFFF,0x0)/VenMedia(C5BD4D42-1A76-4996-8956-73CDA326CD0A)/CDROM(0x1)
     BLK3: Alias(s):
          PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x5,0xFFFF,0x0)/VenMedia(C5BD4D42-1A76-4996-8956-73CDA326CD0A)
     BLK4: Alias(s):
          PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x5,0xFFFF,0x0)/VenMedia(C5BD4D42-1A76-4996-8956-73CDA326CD0A)/CDROM(0x0)

After the patch:
Mapping table
      FS0: Alias(s):CD0f65535a1:;BLK2:
          PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x5,0xFFFF,0x0)/CDROM(0x1)
     BLK0: Alias(s):
          PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x5,0xFFFF,0x0)
     BLK1: Alias(s):
          PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x5,0xFFFF,0x0)/CDROM(0x0)
     BLK3: Alias(s):
          PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x5,0xFFFF,0x0)/VenMedia(C5BD4D42-1A76-4996-8956-73CDA326CD0A)


Since the additional file system is gone:
Tested-by: Hao Wu <hao.a.wu@intel.com>


Best Regards,
Hao Wu

> -----Original Message-----
> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of Paulo
> Alcantara
> Sent: Thursday, September 21, 2017 2:16 AM
> To: edk2-devel@lists.01.org
> Cc: Ni, Ruiyu; Laszlo Ersek; Dong, Eric; Zeng, Star
> Subject: [edk2] [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix creation of
> UDF logical partition
> 
> Do not reserve entire block device size for an UDF file system -
> instead, reserve the appropriate space (UDF logical volume space) for
> it.
> 
> Additionally, only create a logical partition for UDF logical volumes
> that are currently supported by EDK2 UDF file system implementation. For
> instance, an UDF volume with a single LVD and a single Physical (Type 1)
> Partition will be supported.
> 
> Cc: Eric Dong <eric.dong@intel.com>
> Cc: Ruiyu Ni <ruiyu.ni@intel.com>
> Cc: Star Zeng <star.zeng@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Reported-by: Ruiyu Ni <ruiyu.ni@intel.com>
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Paulo Alcantara <pcacjr@zytor.com>
> ---
>  MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c            | 363 ++++++++++--
>  MdeModulePkg/Universal/Disk/UdfDxe/File.c                 |  16 +-
>  MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c | 627
> ++++++++------------
>  MdeModulePkg/Universal/Disk/UdfDxe/Udf.c                  |   7 -
>  MdeModulePkg/Universal/Disk/UdfDxe/Udf.h                  | 158 ++---
>  5 files changed, 606 insertions(+), 565 deletions(-)
> 
> diff --git a/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
> b/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
> index 609f56cef6..572ba7a81a 100644
> --- a/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
> +++ b/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
> @@ -64,11 +64,12 @@ FindAnchorVolumeDescriptorPointer (
>    OUT  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint
>    )
>  {
> -  EFI_STATUS  Status;
> -  UINT32      BlockSize;
> -  EFI_LBA     EndLBA;
> -  EFI_LBA     DescriptorLBAs[4];
> -  UINTN       Index;
> +  EFI_STATUS          Status;
> +  UINT32              BlockSize;
> +  EFI_LBA             EndLBA;
> +  EFI_LBA             DescriptorLBAs[4];
> +  UINTN               Index;
> +  UDF_DESCRIPTOR_TAG  *DescriptorTag;
> 
>    BlockSize = BlockIo->Media->BlockSize;
>    EndLBA = BlockIo->Media->LastBlock;
> @@ -88,10 +89,13 @@ FindAnchorVolumeDescriptorPointer (
>      if (EFI_ERROR (Status)) {
>        return Status;
>      }
> +
> +    DescriptorTag = &AnchorPoint->DescriptorTag;
> +
>      //
>      // Check if read LBA has a valid AVDP descriptor.
>      //
> -    if (IS_AVDP (AnchorPoint)) {
> +    if (DescriptorTag->TagIdentifier == UdfAnchorVolumeDescriptorPointer) {
>        return EFI_SUCCESS;
>      }
>    }
> @@ -102,23 +106,18 @@ FindAnchorVolumeDescriptorPointer (
>  }
> 
>  /**
> -  Check if block device supports a valid UDF file system as specified by OSTA
> -  Universal Disk Format Specification 2.60.
> +  Find UDF volume identifiers in a Volume Recognition Sequence.
> 
> -  @param[in]   BlockIo  BlockIo interface.
> -  @param[in]   DiskIo   DiskIo interface.
> +  @param[in]  BlockIo             BlockIo interface.
> +  @param[in]  DiskIo              DiskIo interface.
> 
> -  @retval EFI_SUCCESS          UDF file system found.
> -  @retval EFI_UNSUPPORTED      UDF file system not found.
> -  @retval EFI_NO_MEDIA         The device has no media.
> -  @retval EFI_DEVICE_ERROR     The device reported an error.
> -  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
> -  @retval EFI_OUT_OF_RESOURCES The scan was not successful due to lack of
> -                               resources.
> +  @retval EFI_SUCCESS             UDF volume identifiers were found.
> +  @retval EFI_NOT_FOUND           UDF volume identifiers were not found.
> +  @retval other                   Failed to perform disk I/O.
> 
>  **/
>  EFI_STATUS
> -SupportUdfFileSystem (
> +FindUdfVolumeIdentifiers (
>    IN EFI_BLOCK_IO_PROTOCOL  *BlockIo,
>    IN EFI_DISK_IO_PROTOCOL   *DiskIo
>    )
> @@ -128,7 +127,6 @@ SupportUdfFileSystem (
>    UINT64                                EndDiskOffset;
>    CDROM_VOLUME_DESCRIPTOR               VolDescriptor;
>    CDROM_VOLUME_DESCRIPTOR               TerminatingVolDescriptor;
> -  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  AnchorPoint;
> 
>    ZeroMem ((VOID *)&TerminatingVolDescriptor, sizeof
> (CDROM_VOLUME_DESCRIPTOR));
> 
> @@ -167,7 +165,7 @@ SupportUdfFileSystem (
>          (CompareMem ((VOID *)&VolDescriptor,
>                       (VOID *)&TerminatingVolDescriptor,
>                       sizeof (CDROM_VOLUME_DESCRIPTOR)) == 0)) {
> -      return EFI_UNSUPPORTED;
> +      return EFI_NOT_FOUND;
>      }
>    }
> 
> @@ -176,7 +174,7 @@ SupportUdfFileSystem (
>    //
>    Offset += UDF_LOGICAL_SECTOR_SIZE;
>    if (Offset >= EndDiskOffset) {
> -    return EFI_UNSUPPORTED;
> +    return EFI_NOT_FOUND;
>    }
> 
>    Status = DiskIo->ReadDisk (
> @@ -196,7 +194,7 @@ SupportUdfFileSystem (
>        (CompareMem ((VOID *)VolDescriptor.Unknown.Id,
>                     (VOID *)UDF_NSR3_IDENTIFIER,
>                     sizeof (VolDescriptor.Unknown.Id)) != 0)) {
> -    return EFI_UNSUPPORTED;
> +    return EFI_NOT_FOUND;
>    }
> 
>    //
> @@ -204,7 +202,7 @@ SupportUdfFileSystem (
>    //
>    Offset += UDF_LOGICAL_SECTOR_SIZE;
>    if (Offset >= EndDiskOffset) {
> -    return EFI_UNSUPPORTED;
> +    return EFI_NOT_FOUND;
>    }
> 
>    Status = DiskIo->ReadDisk (
> @@ -221,15 +219,291 @@ SupportUdfFileSystem (
>    if (CompareMem ((VOID *)VolDescriptor.Unknown.Id,
>                    (VOID *)UDF_TEA_IDENTIFIER,
>                    sizeof (VolDescriptor.Unknown.Id)) != 0) {
> -    return EFI_UNSUPPORTED;
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Check if Logical Volume Descriptor is supported by current EDK2 UDF file
> +  system implementation.
> +
> +  @param[in]  LogicalVolDesc  Logical Volume Descriptor pointer.
> +
> +  @retval TRUE                Logical Volume Descriptor is supported.
> +  @retval FALSE               Logical Volume Descriptor is not supported.
> +
> +**/
> +BOOLEAN
> +IsLogicalVolumeDescriptorSupported (
> +  UDF_LOGICAL_VOLUME_DESCRIPTOR *LogicalVolDesc
> +  )
> +{
> +  //
> +  // Check for a valid UDF revision range
> +  //
> +  switch (UDF_LVD_REVISION (LogicalVolDesc)) {
> +  case 0x0102:
> +  case 0x0150:
> +  case 0x0200:
> +  case 0x0201:
> +  case 0x0250:
> +  case 0x0260:
> +    break;
> +  default:
> +    return FALSE;
> +  }
> +
> +  //
> +  // Check for a single Partition Map
> +  //
> +  if (LogicalVolDesc->NumberOfPartitionMaps > 1) {
> +    return FALSE;
> +  }
> +  //
> +  // UDF 1.02 revision supports only Type 1 (Physical) partitions, but
> +  // let's check it any way.
> +  //
> +  // PartitionMap[0] -> type
> +  // PartitionMap[1] -> length (in bytes)
> +  //
> +  if (LogicalVolDesc->PartitionMaps[0] != 1 ||
> +      LogicalVolDesc->PartitionMaps[1] != 6) {
> +    return FALSE;
> +  }
> +
> +  return TRUE;
> +}
> +
> +/**
> +  Find UDF logical volume location and whether it is supported by current
> EDK2
> +  UDF file system implementation.
> +
> +  @param[in]  BlockIo             BlockIo interface.
> +  @param[in]  DiskIo              DiskIo interface.
> +  @param[in]  AnchorPoint         Anchor volume descriptor pointer.
> +  @param[out] MainVdsStartBlock   Main VDS starting block number.
> +  @param[out] MainVdsEndBlock     Main VDS ending block number.
> +
> +  @retval EFI_SUCCESS             UDF logical volume was found.
> +  @retval EFI_VOLUME_CORRUPTED    UDF file system structures are
> corrupted.
> +  @retval EFI_UNSUPPORTED         UDF logical volume is not supported.
> +  @retval other                   Failed to perform disk I/O.
> +
> +**/
> +EFI_STATUS
> +FindLogicalVolumeLocation (
> +  IN   EFI_BLOCK_IO_PROTOCOL                 *BlockIo,
> +  IN   EFI_DISK_IO_PROTOCOL                  *DiskIo,
> +  IN   UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint,
> +  OUT  UINT64                                *MainVdsStartBlock,
> +  OUT  UINT64                                *MainVdsEndBlock
> +  )
> +{
> +  EFI_STATUS                     Status;
> +  UINT32                         BlockSize;
> +  EFI_LBA                        LastBlock;
> +  UDF_EXTENT_AD                  *ExtentAd;
> +  UINT64                         SeqBlocksNum;
> +  UINT64                         SeqStartBlock;
> +  UINT64                         GuardMainVdsStartBlock;
> +  VOID                           *Buffer;
> +  UINT64                         SeqEndBlock;
> +  BOOLEAN                        StopSequence;
> +  UINTN                          LvdsCount;
> +  UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;
> +  UDF_DESCRIPTOR_TAG             *DescriptorTag;
> +
> +  BlockSize = BlockIo->Media->BlockSize;
> +  LastBlock = BlockIo->Media->LastBlock;
> +  ExtentAd = &AnchorPoint->MainVolumeDescriptorSequenceExtent;
> +
> +  //
> +  // UDF 2.60, 2.2.3.1 struct MainVolumeDescriptorSequenceExtent
> +  //
> +  // The Main Volume Descriptor Sequence Extent shall have a minimum
> length of
> +  // 16 logical sectors.
> +  //
> +  // Also make sure it does not exceed maximum number of blocks in the disk.
> +  //
> +  SeqBlocksNum = DivU64x32 ((UINT64)ExtentAd->ExtentLength, BlockSize);
> +  if (SeqBlocksNum < 16 || (EFI_LBA)SeqBlocksNum > LastBlock + 1) {
> +    return EFI_VOLUME_CORRUPTED;
> +  }
> +
> +  //
> +  // Check for valid Volume Descriptor Sequence starting block number
> +  //
> +  SeqStartBlock = (UINT64)ExtentAd->ExtentLocation;
> +  if (SeqStartBlock > LastBlock ||
> +      SeqStartBlock + SeqBlocksNum - 1 > LastBlock) {
> +    return EFI_VOLUME_CORRUPTED;
>    }
> 
> +  GuardMainVdsStartBlock = SeqStartBlock;
> +
> +  //
> +  // Allocate buffer for reading disk blocks
> +  //
> +  Buffer = AllocateZeroPool ((UINTN)BlockSize);
> +  if (Buffer == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  SeqEndBlock = SeqStartBlock + SeqBlocksNum;
> +  StopSequence = FALSE;
> +  LvdsCount = 0;
> +  Status = EFI_VOLUME_CORRUPTED;
> +  //
> +  // Start Main Volume Descriptor Sequence
> +  //
> +  for (; SeqStartBlock < SeqEndBlock && !StopSequence; SeqStartBlock++) {
> +    //
> +    // Read disk block
> +    //
> +    Status = BlockIo->ReadBlocks (
> +      BlockIo,
> +      BlockIo->Media->MediaId,
> +      SeqStartBlock,
> +      BlockSize,
> +      Buffer
> +      );
> +    if (EFI_ERROR (Status)) {
> +      goto Out_Free;
> +    }
> +
> +    DescriptorTag = Buffer;
> +
> +    //
> +    // ECMA 167, 8.4.1 Contents of a Volume Descriptor Sequence
> +    //
> +    // - A Volume Descriptor Sequence shall contain one or more Primary
> Volume
> +    //   Descriptors.
> +    // - A Volume Descriptor Sequence shall contain zero or more
> Implementation
> +    //   Use Volume Descriptors.
> +    // - A Volume Descriptor Sequence shall contain zero or more Partition
> +    //   Descriptors.
> +    // - A Volume Descriptor Sequence shall contain zero or more Logical
> Volume
> +    //   Descriptors.
> +    // - A Volume Descriptor Sequence shall contain zero or more Unallocated
> +    //   Space Descriptors.
> +    //
> +    switch (UDF_TAG_ID (DescriptorTag)) {
> +    case UdfPrimaryVolumeDescriptor:
> +    case UdfImplemenationUseVolumeDescriptor:
> +    case UdfPartitionDescriptor:
> +    case UdfUnallocatedSpaceDescriptor:
> +      break;
> +
> +    case UdfLogicalVolumeDescriptor:
> +      LogicalVolDesc = Buffer;
> +
> +      //
> +      // Check for existence of a single LVD and whether it is supported by
> +      // current EDK2 UDF file system implementation.
> +      //
> +      if (++LvdsCount > 1 ||
> +          !IsLogicalVolumeDescriptorSupported (LogicalVolDesc)) {
> +        Status = EFI_UNSUPPORTED;
> +        StopSequence = TRUE;
> +      }
> +
> +      break;
> +
> +    case UdfTerminatingDescriptor:
> +      //
> +      // Stop the sequence when we find a Terminating Descriptor
> +      // (aka Unallocated Sector), se we don't have to walk all the unallocated
> +      // area unnecessarily.
> +      //
> +      StopSequence = TRUE;
> +      break;
> +
> +    default:
> +      //
> +      // An invalid Volume Descriptor has been found in the sequece. Volume is
> +      // corrupted.
> +      //
> +      Status = EFI_VOLUME_CORRUPTED;
> +      goto Out_Free;
> +    }
> +  }
> +
> +  //
> +  // Check if LVD was found
> +  //
> +  if (!EFI_ERROR (Status) && LvdsCount == 1) {
> +    *MainVdsStartBlock = GuardMainVdsStartBlock;
> +    //
> +    // We do not need to read either LVD or PD descriptors to know the last
> +    // valid block in the found UDF file system. It's already LastBlock.
> +    //
> +    *MainVdsEndBlock = LastBlock;
> +
> +    Status = EFI_SUCCESS;
> +  }
> +
> +Out_Free:
> +  //
> +  // Free block read buffer
> +  //
> +  FreePool (Buffer);
> +
> +  return Status;
> +}
> +
> +/**
> +  Find a supported UDF file system in block device.
> +
> +  @param[in]  BlockIo             BlockIo interface.
> +  @param[in]  DiskIo              DiskIo interface.
> +  @param[out] StartingLBA         UDF file system starting LBA.
> +  @param[out] EndingLBA           UDF file system starting LBA.
> +
> +  @retval EFI_SUCCESS             UDF file system was found.
> +  @retval other                   UDF file system was not found.
> +
> +**/
> +EFI_STATUS
> +FindUdfFileSystem (
> +  IN EFI_BLOCK_IO_PROTOCOL  *BlockIo,
> +  IN EFI_DISK_IO_PROTOCOL   *DiskIo,
> +  OUT EFI_LBA               *StartingLBA,
> +  OUT EFI_LBA               *EndingLBA
> +  )
> +{
> +  EFI_STATUS Status;
> +  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  AnchorPoint;
> +
> +  //
> +  // Find UDF volume identifiers
> +  //
> +  Status = FindUdfVolumeIdentifiers (BlockIo, DiskIo);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Find Anchor Volume Descriptor Pointer
> +  //
>    Status = FindAnchorVolumeDescriptorPointer (BlockIo, DiskIo, &AnchorPoint);
>    if (EFI_ERROR (Status)) {
> -    return EFI_UNSUPPORTED;
> +    return Status;
>    }
> 
> -  return EFI_SUCCESS;
> +  //
> +  // Find Logical Volume location
> +  //
> +  Status = FindLogicalVolumeLocation (
> +    BlockIo,
> +    DiskIo,
> +    &AnchorPoint,
> +    (UINT64 *)StartingLBA,
> +    (UINT64 *)EndingLBA
> +    );
> +
> +  return Status;
>  }
> 
>  /**
> @@ -263,9 +537,9 @@ PartitionInstallUdfChildHandles (
>    UINT32                       RemainderByMediaBlockSize;
>    EFI_STATUS                   Status;
>    EFI_BLOCK_IO_MEDIA           *Media;
> -  EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode;
> -  EFI_GUID                     *VendorDefinedGuid;
>    EFI_PARTITION_INFO_PROTOCOL  PartitionInfo;
> +  EFI_LBA                      StartingLBA;
> +  EFI_LBA                      EndingLBA;
> 
>    Media = BlockIo->Media;
> 
> @@ -281,35 +555,10 @@ PartitionInstallUdfChildHandles (
>      return EFI_NOT_FOUND;
>    }
> 
> -  DevicePathNode = DevicePath;
> -  while (!IsDevicePathEnd (DevicePathNode)) {
> -    //
> -    // Do not allow checking for UDF file systems in CDROM "El Torito"
> -    // partitions, and skip duplicate installation of UDF file system child
> -    // nodes.
> -    //
> -    if (DevicePathType (DevicePathNode) == MEDIA_DEVICE_PATH) {
> -      if (DevicePathSubType (DevicePathNode) == MEDIA_CDROM_DP) {
> -        return EFI_NOT_FOUND;
> -      }
> -      if (DevicePathSubType (DevicePathNode) == MEDIA_VENDOR_DP) {
> -        VendorDefinedGuid = (EFI_GUID *)((UINTN)DevicePathNode +
> -                                         OFFSET_OF (VENDOR_DEVICE_PATH, Guid));
> -        if (CompareGuid (VendorDefinedGuid, &gUdfDevPathGuid)) {
> -          return EFI_NOT_FOUND;
> -        }
> -      }
> -    }
> -    //
> -    // Try next device path node
> -    //
> -    DevicePathNode = NextDevicePathNode (DevicePathNode);
> -  }
> -
>    //
> -  // Check if block device supports an UDF file system
> +  // Search for an UDF file system on block device
>    //
> -  Status = SupportUdfFileSystem (BlockIo, DiskIo);
> +  Status = FindUdfFileSystem (BlockIo, DiskIo, &StartingLBA, &EndingLBA);
>    if (EFI_ERROR (Status)) {
>      return EFI_NOT_FOUND;
>    }
> @@ -334,8 +583,8 @@ PartitionInstallUdfChildHandles (
>      DevicePath,
>      (EFI_DEVICE_PATH_PROTOCOL *)&gUdfDevicePath,
>      &PartitionInfo,
> -    0,
> -    Media->LastBlock,
> +    StartingLBA,
> +    EndingLBA,
>      Media->BlockSize
>      );
>    if (!EFI_ERROR (Status)) {
> diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/File.c
> b/MdeModulePkg/Universal/Disk/UdfDxe/File.c
> index 625f2c5637..6f07bf2066 100644
> --- a/MdeModulePkg/Universal/Disk/UdfDxe/File.c
> +++ b/MdeModulePkg/Universal/Disk/UdfDxe/File.c
> @@ -131,7 +131,6 @@ Error_Alloc_Priv_File_Data:
>    CleanupFileInformation (&PrivFsData->Root);
> 
>  Error_Find_Root_Dir:
> -  CleanupVolumeInformation (&PrivFsData->Volume);
> 
>  Error_Read_Udf_Volume:
>  Error_Invalid_Params:
> @@ -429,7 +428,7 @@ UdfRead (
>      }
>      ASSERT (NewFileEntryData != NULL);
> 
> -    if (IS_FE_SYMLINK (NewFileEntryData)) {
> +    if (FE_ICB_FILE_TYPE (NewFileEntryData) == UdfFileEntrySymlink) {
>        Status = ResolveSymlink (
>          BlockIo,
>          DiskIo,
> @@ -529,7 +528,6 @@ UdfClose (
>    EFI_TPL                     OldTpl;
>    EFI_STATUS                  Status;
>    PRIVATE_UDF_FILE_DATA       *PrivFileData;
> -  PRIVATE_UDF_SIMPLE_FS_DATA  *PrivFsData;
> 
>    OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
> 
> @@ -542,8 +540,6 @@ UdfClose (
> 
>    PrivFileData = PRIVATE_UDF_FILE_DATA_FROM_THIS (This);
> 
> -  PrivFsData = PRIVATE_UDF_SIMPLE_FS_DATA_FROM_THIS (PrivFileData-
> >SimpleFs);
> -
>    if (!PrivFileData->IsRootDirectory) {
>      CleanupFileInformation (&PrivFileData->File);
> 
> @@ -552,10 +548,6 @@ UdfClose (
>      }
>    }
> 
> -  if (--PrivFsData->OpenFiles == 0) {
> -    CleanupVolumeInformation (&PrivFsData->Volume);
> -  }
> -
>    FreePool ((VOID *)PrivFileData);
> 
>  Exit:
> @@ -652,7 +644,7 @@ UdfGetPosition (
>    // As per UEFI spec, if the file handle is a directory, then the current file
>    // position has no meaning and the operation is not supported.
>    //
> -  if (IS_FID_DIRECTORY_FILE (&PrivFileData->File.FileIdentifierDesc)) {
> +  if (IS_FID_DIRECTORY_FILE (PrivFileData->File.FileIdentifierDesc)) {
>      return  EFI_UNSUPPORTED;
>    }
> 
> @@ -788,7 +780,7 @@ UdfGetInfo (
>    } else if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {
>      String = VolumeLabel;
> 
> -    FileSetDesc = PrivFsData->Volume.FileSetDescs[0];
> +    FileSetDesc = &PrivFsData->Volume.FileSetDesc;
> 
>      OstaCompressed = &FileSetDesc->LogicalVolumeIdentifier[0];
> 
> @@ -847,7 +839,7 @@ UdfGetInfo (
>      FileSystemInfo->Size        = FileSystemInfoLength;
>      FileSystemInfo->ReadOnly    = TRUE;
>      FileSystemInfo->BlockSize   =
> -      LV_BLOCK_SIZE (&PrivFsData->Volume, UDF_DEFAULT_LV_NUM);
> +      PrivFsData->Volume.LogicalVolDesc.LogicalBlockSize;
>      FileSystemInfo->VolumeSize  = VolumeSize;
>      FileSystemInfo->FreeSpace   = FreeSpaceSize;
> 
> diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
> b/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
> index 5df267761f..62d817989f 100644
> --- a/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
> +++ b/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
> @@ -38,11 +38,12 @@ FindAnchorVolumeDescriptorPointer (
>    OUT  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint
>    )
>  {
> -  EFI_STATUS  Status;
> -  UINT32      BlockSize;
> -  EFI_LBA     EndLBA;
> -  EFI_LBA     DescriptorLBAs[4];
> -  UINTN       Index;
> +  EFI_STATUS          Status;
> +  UINT32              BlockSize;
> +  EFI_LBA             EndLBA;
> +  EFI_LBA             DescriptorLBAs[4];
> +  UINTN               Index;
> +  UDF_DESCRIPTOR_TAG  *DescriptorTag;
> 
>    BlockSize = BlockIo->Media->BlockSize;
>    EndLBA = BlockIo->Media->LastBlock;
> @@ -62,10 +63,13 @@ FindAnchorVolumeDescriptorPointer (
>      if (EFI_ERROR (Status)) {
>        return Status;
>      }
> +
> +    DescriptorTag = &AnchorPoint->DescriptorTag;
> +
>      //
>      // Check if read LBA has a valid AVDP descriptor.
>      //
> -    if (IS_AVDP (AnchorPoint)) {
> +    if (DescriptorTag->TagIdentifier == UdfAnchorVolumeDescriptorPointer) {
>        return EFI_SUCCESS;
>      }
>    }
> @@ -99,148 +103,98 @@ StartMainVolumeDescriptorSequence (
>    OUT  UDF_VOLUME_INFO                       *Volume
>    )
>  {
> -  EFI_STATUS                     Status;
> -  UINT32                         BlockSize;
> -  UDF_EXTENT_AD                  *ExtentAd;
> -  UINT64                         StartingLsn;
> -  UINT64                         EndingLsn;
> -  VOID                           *Buffer;
> -  UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;
> -  UDF_PARTITION_DESCRIPTOR       *PartitionDesc;
> -  UINTN                          Index;
> -  UINT32                         LogicalBlockSize;
> +  EFI_STATUS            Status;
> +  UINT32                BlockSize;
> +  UDF_EXTENT_AD         *ExtentAd;
> +  EFI_LBA               SeqStartBlock;
> +  EFI_LBA               SeqEndBlock;
> +  BOOLEAN               StopSequence;
> +  VOID                  *Buffer;
> +  UDF_DESCRIPTOR_TAG    *DescriptorTag;
> +  UINT32                LogicalBlockSize;
> +
> +  BlockSize = BlockIo->Media->BlockSize;
> +  ExtentAd = &AnchorPoint->MainVolumeDescriptorSequenceExtent;
> 
>    //
> -  // We've already found an ADVP on the volume. It contains the extent
> -  // (MainVolumeDescriptorSequenceExtent) where the Main Volume
> Descriptor
> -  // Sequence starts. Therefore, we'll look for Logical Volume Descriptors and
> -  // Partitions Descriptors and save them in memory, accordingly.
> -  //
> -  // Note also that each descriptor will be aligned on a block size (BlockSize)
> -  // boundary, so we need to read one block at a time.
> +  // Allocate buffer for reading disk blocks
>    //
> -  BlockSize    = BlockIo->Media->BlockSize;
> -  ExtentAd     = &AnchorPoint->MainVolumeDescriptorSequenceExtent;
> -  StartingLsn  = (UINT64)ExtentAd->ExtentLocation;
> -  EndingLsn    = StartingLsn + DivU64x32 (
> -                                     (UINT64)ExtentAd->ExtentLength,
> -                                     BlockSize
> -                                     );
> -
> -  Volume->LogicalVolDescs =
> -    (UDF_LOGICAL_VOLUME_DESCRIPTOR **)AllocateZeroPool (ExtentAd-
> >ExtentLength);
> -  if (Volume->LogicalVolDescs == NULL) {
> -    return EFI_OUT_OF_RESOURCES;
> -  }
> -
> -  Volume->PartitionDescs =
> -    (UDF_PARTITION_DESCRIPTOR **)AllocateZeroPool (ExtentAd-
> >ExtentLength);
> -  if (Volume->PartitionDescs == NULL) {
> -    Status = EFI_OUT_OF_RESOURCES;
> -    goto Error_Alloc_Pds;
> -  }
> -
> -  Buffer = AllocateZeroPool (BlockSize);
> +  Buffer = AllocateZeroPool ((UINTN)BlockSize);
>    if (Buffer == NULL) {
> -    Status = EFI_OUT_OF_RESOURCES;
> -    goto Error_Alloc_Buf;
> +    return EFI_OUT_OF_RESOURCES;
>    }
> 
> -  Volume->LogicalVolDescsNo  = 0;
> -  Volume->PartitionDescsNo   = 0;
> -
> -  while (StartingLsn <= EndingLsn) {
> -    Status = DiskIo->ReadDisk (
> -      DiskIo,
> +  //
> +  // The logical partition created by Partition driver is relative to the main
> +  // VDS extent location, so we start the Main Volume Descriptor Sequence at
> +  // LBA 0.
> +  //
> +  // We don't need to check again if we have valid Volume Descriptors here
> since
> +  // Partition driver already did.
> +  //
> +  SeqStartBlock = 0;
> +  SeqEndBlock = SeqStartBlock + DivU64x32 ((UINT64)ExtentAd->ExtentLength,
> +                                           BlockSize);
> +  StopSequence = FALSE;
> +  for (; SeqStartBlock < SeqEndBlock && !StopSequence; SeqStartBlock++) {
> +    //
> +    // Read disk block
> +    //
> +    Status = BlockIo->ReadBlocks (
> +      BlockIo,
>        BlockIo->Media->MediaId,
> -      MultU64x32 (StartingLsn, BlockSize),
> +      SeqStartBlock,
>        BlockSize,
>        Buffer
>        );
>      if (EFI_ERROR (Status)) {
> -      goto Error_Read_Disk_Blk;
> +      goto Out_Free;
>      }
> 
> -    if (IS_TD (Buffer)) {
> +    DescriptorTag = Buffer;
> +
> +    switch (UDF_TAG_ID (DescriptorTag)) {
> +    case UdfPartitionDescriptor:
>        //
> -      // Found a Terminating Descriptor. Stop the sequence then.
> +      // Save Partition Descriptor
>        //
> +      CopyMem (&Volume->PartitionDesc, Buffer, sizeof (Volume-
> >PartitionDesc));
>        break;
> -    }
> 
> -    if (IS_LVD (Buffer)) {
> +    case UdfLogicalVolumeDescriptor:
>        //
> -      // Found a Logical Volume Descriptor.
> +      // Save Logical Volume Descriptor
>        //
> -      LogicalVolDesc =
> -        (UDF_LOGICAL_VOLUME_DESCRIPTOR *)
> -        AllocateZeroPool (sizeof (UDF_LOGICAL_VOLUME_DESCRIPTOR));
> -      if (LogicalVolDesc == NULL) {
> -        Status = EFI_OUT_OF_RESOURCES;
> -        goto Error_Alloc_Lvd;
> -      }
> +      CopyMem (&Volume->LogicalVolDesc, Buffer, sizeof (Volume-
> >LogicalVolDesc));
> +      break;
> 
> -      CopyMem ((VOID *)LogicalVolDesc, Buffer,
> -               sizeof (UDF_LOGICAL_VOLUME_DESCRIPTOR));
> -      Volume->LogicalVolDescs[Volume->LogicalVolDescsNo++] =
> LogicalVolDesc;
> -    } else if (IS_PD (Buffer)) {
> -      //
> -      // Found a Partition Descriptor.
> -      //
> -      PartitionDesc =
> -        (UDF_PARTITION_DESCRIPTOR *)
> -        AllocateZeroPool (sizeof (UDF_PARTITION_DESCRIPTOR));
> -      if (PartitionDesc == NULL) {
> -        Status = EFI_OUT_OF_RESOURCES;
> -        goto Error_Alloc_Pd;
> -      }
> +    case UdfTerminatingDescriptor:
> +      StopSequence = TRUE;
> +      break;
> 
> -      CopyMem ((VOID *)PartitionDesc, Buffer,
> -               sizeof (UDF_PARTITION_DESCRIPTOR));
> -      Volume->PartitionDescs[Volume->PartitionDescsNo++] = PartitionDesc;
> +    default:
> +      ;
>      }
> -
> -    StartingLsn++;
>    }
> 
>    //
> -  // When an UDF volume (revision 2.00 or higher) contains a File Entry rather
> -  // than an Extended File Entry (which is not recommended as per spec), we
> need
> -  // to make sure the size of a FE will be _at least_ 2048
> -  // (UDF_LOGICAL_SECTOR_SIZE) bytes long to keep backward compatibility.
> +  // Determine FE (File Entry) size
>    //
> -  LogicalBlockSize = LV_BLOCK_SIZE (Volume, UDF_DEFAULT_LV_NUM);
> +  LogicalBlockSize = Volume->LogicalVolDesc.LogicalBlockSize;
>    if (LogicalBlockSize >= UDF_LOGICAL_SECTOR_SIZE) {
> -    Volume->FileEntrySize = LogicalBlockSize;
> +    Volume->FileEntrySize = (UINTN)LogicalBlockSize;
>    } else {
>      Volume->FileEntrySize = UDF_LOGICAL_SECTOR_SIZE;
>    }
> 
> -  FreePool (Buffer);
> +  Status = EFI_SUCCESS;
> 
> -  return EFI_SUCCESS;
> -
> -Error_Alloc_Pd:
> -Error_Alloc_Lvd:
> -  for (Index = 0; Index < Volume->PartitionDescsNo; Index++) {
> -    FreePool ((VOID *)Volume->PartitionDescs[Index]);
> -  }
> -
> -  for (Index = 0; Index < Volume->LogicalVolDescsNo; Index++) {
> -    FreePool ((VOID *)Volume->LogicalVolDescs[Index]);
> -  }
> -
> -Error_Read_Disk_Blk:
> +Out_Free:
> +  //
> +  // Free block read buffer
> +  //
>    FreePool (Buffer);
> 
> -Error_Alloc_Buf:
> -  FreePool ((VOID *)Volume->PartitionDescs);
> -  Volume->PartitionDescs = NULL;
> -
> -Error_Alloc_Pds:
> -  FreePool ((VOID *)Volume->LogicalVolDescs);
> -  Volume->LogicalVolDescs = NULL;
> -
>    return Status;
>  }
> 
> @@ -262,48 +216,53 @@ GetPdFromLongAd (
>    )
>  {
>    UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;
> -  UINTN                          Index;
> -  UDF_PARTITION_DESCRIPTOR       *PartitionDesc;
>    UINT16                         PartitionNum;
> 
> -  LogicalVolDesc = Volume->LogicalVolDescs[UDF_DEFAULT_LV_NUM];
> +  LogicalVolDesc = &Volume->LogicalVolDesc;
> 
> -  switch (LV_UDF_REVISION (LogicalVolDesc)) {
> +  switch (UDF_LVD_REVISION (LogicalVolDesc)) {
>    case 0x0102:
> +  case 0x0150:
> +  case 0x0200:
> +  case 0x0201:
> +  case 0x0250:
> +  case 0x0260:
>      //
> -    // As per UDF 1.02 specification:
> +    // UDF 1.02 specification:
>      //
>      // There shall be exactly one prevailing Logical Volume Descriptor recorded
>      // per Volume Set. The Partition Maps field shall contain only Type 1
>      // Partition Maps.
>      //
> -    PartitionNum = *(UINT16 *)((UINTN)&LogicalVolDesc->PartitionMaps[4]);
> -    break;
> -  case 0x0150:
> +    // UDF 1.50 through 2.60 specs say:
>      //
> -    // Ensure Type 1 Partition map. Other types aren't supported in this
> -    // implementation.
> +    // For the purpose of interchange partition maps shall be limited to
> +    // Partition Map type 1, except type 2 maps as described in the document.
> +    //
> +    // NOTE: Only one Type 1 (Physical) Partition is supported. It has been
> +    // checked already in Partition driver for existence of a single Type 1
> +    // Partition map, so we don't have to double check here.
> +    //
> +    // Partition reference number can also be retrieved from
> +    // LongAd->ExtentLocation.PartitionReferenceNumber, however the spec
> says
> +    // it may be 0, so let's not rely on it.
>      //
> -    if (LogicalVolDesc->PartitionMaps[0] != 1 ||
> -        LogicalVolDesc->PartitionMaps[1] != 6) {
> -      return NULL;
> -    }
>      PartitionNum = *(UINT16 *)((UINTN)&LogicalVolDesc->PartitionMaps[4]);
>      break;
> -  case 0x0260:
> +
> +  default:
>      //
> -    // Fall through.
> +    // Unsupported UDF revision
>      //
> -  default:
> -    PartitionNum = LongAd->ExtentLocation.PartitionReferenceNumber;
> -    break;
> +    return NULL;
>    }
> 
> -  for (Index = 0; Index < Volume->PartitionDescsNo; Index++) {
> -    PartitionDesc = Volume->PartitionDescs[Index];
> -    if (PartitionDesc->PartitionNumber == PartitionNum) {
> -      return PartitionDesc;
> -    }
> +  //
> +  // Check if partition number matches Partition Descriptor found in Main
> Volume
> +  // Descriptor Sequence.
> +  //
> +  if (Volume->PartitionDesc.PartitionNumber == PartitionNum) {
> +    return &Volume->PartitionDesc;
>    }
> 
>    return NULL;
> @@ -329,13 +288,15 @@ GetLongAdLsn (
>    PartitionDesc = GetPdFromLongAd (Volume, LongAd);
>    ASSERT (PartitionDesc != NULL);
> 
> -  return (UINT64)PartitionDesc->PartitionStartingLocation +
> -                 LongAd->ExtentLocation.LogicalBlockNumber;
> +  return (UINT64)PartitionDesc->PartitionStartingLocation -
> +    Volume->MainVdsStartLocation +
> +    LongAd->ExtentLocation.LogicalBlockNumber;
>  }
> 
>  /**
>    Return logical sector number of a given Short Allocation Descriptor.
> 
> +  @param[in]  Volume              Volume pointer.
>    @param[in]  PartitionDesc       Partition Descriptor pointer.
>    @param[in]  ShortAd             Short Allocation Descriptor pointer.
> 
> @@ -344,14 +305,13 @@ GetLongAdLsn (
>  **/
>  UINT64
>  GetShortAdLsn (
> +  IN UDF_VOLUME_INFO                  *Volume,
>    IN UDF_PARTITION_DESCRIPTOR         *PartitionDesc,
>    IN UDF_SHORT_ALLOCATION_DESCRIPTOR  *ShortAd
>    )
>  {
> -  ASSERT (PartitionDesc != NULL);
> -
> -  return (UINT64)PartitionDesc->PartitionStartingLocation +
> -    ShortAd->ExtentPosition;
> +  return (UINT64)PartitionDesc->PartitionStartingLocation -
> +    Volume->MainVdsStartLocation + ShortAd->ExtentPosition;
>  }
> 
>  /**
> @@ -363,8 +323,6 @@ GetShortAdLsn (
>    @param[in]  BlockIo             BlockIo interface.
>    @param[in]  DiskIo              DiskIo interface.
>    @param[in]  Volume              Volume information pointer.
> -  @param[in]  LogicalVolDescNum   Index of Logical Volume Descriptor
> -  @param[out] FileSetDesc         File Set Descriptor pointer.
> 
>    @retval EFI_SUCCESS             File Set Descriptor pointer found.
>    @retval EFI_VOLUME_CORRUPTED    The file system structures are
> corrupted.
> @@ -375,36 +333,42 @@ EFI_STATUS
>  FindFileSetDescriptor (
>    IN   EFI_BLOCK_IO_PROTOCOL    *BlockIo,
>    IN   EFI_DISK_IO_PROTOCOL     *DiskIo,
> -  IN   UDF_VOLUME_INFO          *Volume,
> -  IN   UINTN                    LogicalVolDescNum,
> -  OUT  UDF_FILE_SET_DESCRIPTOR  *FileSetDesc
> +  IN   UDF_VOLUME_INFO          *Volume
>    )
>  {
>    EFI_STATUS                     Status;
>    UINT64                         Lsn;
>    UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;
> +  UDF_DESCRIPTOR_TAG             *DescriptorTag;
> 
> -  LogicalVolDesc = Volume->LogicalVolDescs[LogicalVolDescNum];
> +  LogicalVolDesc = &Volume->LogicalVolDesc;
>    Lsn = GetLongAdLsn (Volume, &LogicalVolDesc->LogicalVolumeContentsUse);
> 
>    //
> -  // Read extent (Long Ad).
> +  // As per UDF 2.60 specification:
> +  //
> +  // There shall be exactly one File Set Descriptor recorded per Logical
> +  // Volume.
> +  //
> +  // Read disk block
>    //
>    Status = DiskIo->ReadDisk (
>      DiskIo,
>      BlockIo->Media->MediaId,
>      MultU64x32 (Lsn, LogicalVolDesc->LogicalBlockSize),
> -    sizeof (UDF_FILE_SET_DESCRIPTOR),
> -    (VOID *)FileSetDesc
> +    sizeof (Volume->FileSetDesc),
> +    &Volume->FileSetDesc
>      );
>    if (EFI_ERROR (Status)) {
>      return Status;
>    }
> 
> +  DescriptorTag = &Volume->FileSetDesc.DescriptorTag;
> +
>    //
> -  // Check if the read extent contains a valid FSD's tag identifier.
> +  // Check if read block is a File Set Descriptor
>    //
> -  if (!IS_FSD (FileSetDesc)) {
> +  if (UDF_TAG_ID (DescriptorTag) != UdfFileSetDescriptor) {
>      return EFI_VOLUME_CORRUPTED;
>    }
> 
> @@ -412,82 +376,6 @@ FindFileSetDescriptor (
>  }
> 
>  /**
> -  Get all File Set Descriptors for each Logical Volume Descriptor.
> -
> -  @param[in]      BlockIo         BlockIo interface.
> -  @param[in]      DiskIo          DiskIo interface.
> -  @param[in, out] Volume          Volume information pointer.
> -
> -  @retval EFI_SUCCESS             File Set Descriptors were got.
> -  @retval EFI_OUT_OF_RESOURCES    File Set Descriptors were not got due to
> lack
> -                                  of resources.
> -  @retval other                   Error occured when finding File Set
> -                                  Descriptor in Logical Volume Descriptor.
> -
> -**/
> -EFI_STATUS
> -GetFileSetDescriptors (
> -  IN      EFI_BLOCK_IO_PROTOCOL  *BlockIo,
> -  IN      EFI_DISK_IO_PROTOCOL   *DiskIo,
> -  IN OUT  UDF_VOLUME_INFO        *Volume
> -  )
> -{
> -  EFI_STATUS               Status;
> -  UINTN                    Index;
> -  UDF_FILE_SET_DESCRIPTOR  *FileSetDesc;
> -  UINTN                    Count;
> -
> -  Volume->FileSetDescs =
> -    (UDF_FILE_SET_DESCRIPTOR **)AllocateZeroPool (
> -      Volume->LogicalVolDescsNo * sizeof (UDF_FILE_SET_DESCRIPTOR));
> -  if (Volume->FileSetDescs == NULL) {
> -    return EFI_OUT_OF_RESOURCES;
> -  }
> -
> -  for (Index = 0; Index < Volume->LogicalVolDescsNo; Index++) {
> -    FileSetDesc = AllocateZeroPool (sizeof (UDF_FILE_SET_DESCRIPTOR));
> -    if (FileSetDesc == NULL) {
> -      Status = EFI_OUT_OF_RESOURCES;
> -      goto Error_Alloc_Fsd;
> -    }
> -
> -    //
> -    // Find a FSD for this LVD.
> -    //
> -    Status = FindFileSetDescriptor (
> -      BlockIo,
> -      DiskIo,
> -      Volume,
> -      Index,
> -      FileSetDesc
> -      );
> -    if (EFI_ERROR (Status)) {
> -      goto Error_Find_Fsd;
> -    }
> -
> -    //
> -    // Got one. Save it.
> -    //
> -    Volume->FileSetDescs[Index] = FileSetDesc;
> -  }
> -
> -  Volume->FileSetDescsNo = Volume->LogicalVolDescsNo;
> -  return EFI_SUCCESS;
> -
> -Error_Find_Fsd:
> -  Count = Index + 1;
> -  for (Index = 0; Index < Count; Index++) {
> -    FreePool ((VOID *)Volume->FileSetDescs[Index]);
> -  }
> -
> -  FreePool ((VOID *)Volume->FileSetDescs);
> -  Volume->FileSetDescs = NULL;
> -
> -Error_Alloc_Fsd:
> -  return Status;
> -}
> -
> -/**
>    Read Volume and File Structure on an UDF file system.
> 
>    @param[in]   BlockIo            BlockIo interface.
> @@ -507,9 +395,10 @@ ReadVolumeFileStructure (
>  {
>    EFI_STATUS                            Status;
>    UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  AnchorPoint;
> +  UDF_EXTENT_AD                         *ExtentAd;
> 
>    //
> -  // Find an AVDP.
> +  // Find Anchor Volume Descriptor Pointer
>    //
>    Status = FindAnchorVolumeDescriptorPointer (
>      BlockIo,
> @@ -521,7 +410,14 @@ ReadVolumeFileStructure (
>    }
> 
>    //
> -  // AVDP has been found. Start MVDS.
> +  // Save Main VDS start block number
> +  //
> +  ExtentAd = &AnchorPoint.MainVolumeDescriptorSequenceExtent;
> +
> +  Volume->MainVdsStartLocation = (UINT64)ExtentAd->ExtentLocation;
> +
> +  //
> +  // Start Main Volume Descriptor Sequence.
>    //
>    Status = StartMainVolumeDescriptorSequence (
>      BlockIo,
> @@ -620,16 +516,19 @@ GetFileEntryData (
>    OUT  UINT64  *Length
>    )
>  {
> +  UDF_DESCRIPTOR_TAG       *DescriptorTag;
>    UDF_EXTENDED_FILE_ENTRY  *ExtendedFileEntry;
>    UDF_FILE_ENTRY           *FileEntry;
> 
> -  if (IS_EFE (FileEntryData)) {
> +  DescriptorTag = FileEntryData;
> +
> +  if (UDF_TAG_ID (DescriptorTag) == UdfExtendedFileEntry) {
>      ExtendedFileEntry = (UDF_EXTENDED_FILE_ENTRY *)FileEntryData;
> 
>      *Length  = ExtendedFileEntry->InformationLength;
>      *Data    = (VOID *)((UINT8 *)ExtendedFileEntry->Data +
>                          ExtendedFileEntry->LengthOfExtendedAttributes);
> -  } else if (IS_FE (FileEntryData)) {
> +  } else if (UDF_TAG_ID (DescriptorTag) == UdfFileEntry) {
>      FileEntry = (UDF_FILE_ENTRY *)FileEntryData;
> 
>      *Length  = FileEntry->InformationLength;
> @@ -654,16 +553,19 @@ GetAdsInformation (
>    OUT  UINT64  *Length
>    )
>  {
> +  UDF_DESCRIPTOR_TAG       *DescriptorTag;
>    UDF_EXTENDED_FILE_ENTRY  *ExtendedFileEntry;
>    UDF_FILE_ENTRY           *FileEntry;
> 
> -  if (IS_EFE (FileEntryData)) {
> +  DescriptorTag = FileEntryData;
> +
> +  if (UDF_TAG_ID (DescriptorTag) == UdfExtendedFileEntry) {
>      ExtendedFileEntry = (UDF_EXTENDED_FILE_ENTRY *)FileEntryData;
> 
>      *Length = ExtendedFileEntry->LengthOfAllocationDescriptors;
>      *AdsData = (VOID *)((UINT8 *)ExtendedFileEntry->Data +
>                          ExtendedFileEntry->LengthOfExtendedAttributes);
> -  } else if (IS_FE (FileEntryData)) {
> +  } else if (UDF_TAG_ID (DescriptorTag) == UdfFileEntry) {
>      FileEntry = (UDF_FILE_ENTRY *)FileEntryData;
> 
>      *Length = FileEntry->LengthOfAllocationDescriptors;
> @@ -850,6 +752,7 @@ GetAllocationDescriptorLsn (
>      return GetLongAdLsn (Volume, (UDF_LONG_ALLOCATION_DESCRIPTOR
> *)Ad);
>    } else if (RecordingFlags == ShortAdsSequence) {
>      return GetShortAdLsn (
> +      Volume,
>        GetPdFromLongAd (Volume, ParentIcb),
>        (UDF_SHORT_ALLOCATION_DESCRIPTOR *)Ad
>        );
> @@ -897,6 +800,7 @@ GetAedAdsOffset (
>    VOID                              *Data;
>    UINT32                            LogicalBlockSize;
>    UDF_ALLOCATION_EXTENT_DESCRIPTOR  *AllocExtDesc;
> +  UDF_DESCRIPTOR_TAG                *DescriptorTag;
> 
>    ExtentLength  = GET_EXTENT_LENGTH (RecordingFlags, Ad);
>    Lsn           = GetAllocationDescriptorLsn (RecordingFlags,
> @@ -909,7 +813,7 @@ GetAedAdsOffset (
>      return EFI_OUT_OF_RESOURCES;
>    }
> 
> -  LogicalBlockSize = LV_BLOCK_SIZE (Volume, UDF_DEFAULT_LV_NUM);
> +  LogicalBlockSize = Volume->LogicalVolDesc.LogicalBlockSize;
> 
>    //
>    // Read extent.
> @@ -925,11 +829,14 @@ GetAedAdsOffset (
>      goto Exit;
>    }
> 
> +  AllocExtDesc = (UDF_ALLOCATION_EXTENT_DESCRIPTOR *)Data;
> +
> +  DescriptorTag = &AllocExtDesc->DescriptorTag;
> +
>    //
>    // Check if read extent contains a valid tag identifier for AED.
>    //
> -  AllocExtDesc = (UDF_ALLOCATION_EXTENT_DESCRIPTOR *)Data;
> -  if (!IS_AED (AllocExtDesc)) {
> +  if (UDF_TAG_ID (DescriptorTag) != UdfAllocationExtentDescriptor) {
>      Status = EFI_VOLUME_CORRUPTED;
>      goto Exit;
>    }
> @@ -1102,7 +1009,7 @@ ReadFile (
>    UINT32                  ExtentLength;
>    UDF_FE_RECORDING_FLAGS  RecordingFlags;
> 
> -  LogicalBlockSize  = LV_BLOCK_SIZE (Volume, UDF_DEFAULT_LV_NUM);
> +  LogicalBlockSize  = Volume->LogicalVolDesc.LogicalBlockSize;
>    DoFreeAed         = FALSE;
> 
>    //
> @@ -1444,7 +1351,7 @@ InternalFindFile (
>    //
>    // Check if parent file is really directory.
>    //
> -  if (!IS_FE_DIRECTORY (Parent->FileEntry)) {
> +  if (FE_ICB_FILE_TYPE (Parent->FileEntry) != UdfFileEntryDirectory) {
>      return EFI_NOT_FOUND;
>    }
> 
> @@ -1489,7 +1396,7 @@ InternalFindFile (
>        break;
>      }
> 
> -    if (IS_FID_PARENT_FILE (FileIdentifierDesc)) {
> +    if (FileIdentifierDesc->FileCharacteristics & PARENT_FILE) {
>        //
>        // This FID contains the location (FE/EFE) of the parent directory of this
>        // directory (Parent), and if FileName is either ".." or "\\", then it's
> @@ -1592,6 +1499,9 @@ ReadUdfVolumeInformation (
>  {
>    EFI_STATUS Status;
> 
> +  //
> +  // Read all necessary UDF volume information and keep it private to the
> driver
> +  //
>    Status = ReadVolumeFileStructure (
>      BlockIo,
>      DiskIo,
> @@ -1601,13 +1511,12 @@ ReadUdfVolumeInformation (
>      return Status;
>    }
> 
> -  Status = GetFileSetDescriptors (
> -    BlockIo,
> -    DiskIo,
> -    Volume
> -    );
> +  //
> +  // Find File Set Descriptor
> +  //
> +  Status = FindFileSetDescriptor (BlockIo, DiskIo, Volume);
>    if (EFI_ERROR (Status)) {
> -    CleanupVolumeInformation (Volume);
> +    return Status;
>    }
> 
>    return Status;
> @@ -1644,7 +1553,7 @@ FindRootDirectory (
>      BlockIo,
>      DiskIo,
>      Volume,
> -    &Volume->FileSetDescs[0]->RootDirectoryIcb,
> +    &Volume->FileSetDesc.RootDirectoryIcb,
>      &File->FileEntry
>      );
>    if (EFI_ERROR (Status)) {
> @@ -1661,7 +1570,7 @@ FindRootDirectory (
>      L"\\",
>      NULL,
>      &Parent,
> -    &Volume->FileSetDescs[0]->RootDirectoryIcb,
> +    &Volume->FileSetDesc.RootDirectoryIcb,
>      File
>      );
>    if (EFI_ERROR (Status)) {
> @@ -1697,12 +1606,13 @@ FindFileEntry (
>    OUT  VOID                            **FileEntry
>    )
>  {
> -  EFI_STATUS  Status;
> -  UINT64      Lsn;
> -  UINT32      LogicalBlockSize;
> +  EFI_STATUS          Status;
> +  UINT64              Lsn;
> +  UINT32              LogicalBlockSize;
> +  UDF_DESCRIPTOR_TAG  *DescriptorTag;
> 
>    Lsn               = GetLongAdLsn (Volume, Icb);
> -  LogicalBlockSize  = LV_BLOCK_SIZE (Volume, UDF_DEFAULT_LV_NUM);
> +  LogicalBlockSize  = Volume->LogicalVolDesc.LogicalBlockSize;
> 
>    *FileEntry = AllocateZeroPool (Volume->FileEntrySize);
>    if (*FileEntry == NULL) {
> @@ -1723,11 +1633,14 @@ FindFileEntry (
>      goto Error_Read_Disk_Blk;
>    }
> 
> +  DescriptorTag = *FileEntry;
> +
>    //
>    // Check if the read extent contains a valid Tag Identifier for the expected
>    // FE/EFE.
>    //
> -  if (!IS_FE (*FileEntry) && !IS_EFE (*FileEntry)) {
> +  if (UDF_TAG_ID (DescriptorTag) != UdfFileEntry &&
> +      UDF_TAG_ID (DescriptorTag) != UdfExtendedFileEntry) {
>      Status = EFI_VOLUME_CORRUPTED;
>      goto Error_Invalid_Fe;
>    }
> @@ -1837,7 +1750,7 @@ FindFile (
>      // If the found file is a symlink, then find its respective FE/EFE and
>      // FID descriptors.
>      //
> -    if (IS_FE_SYMLINK (File->FileEntry)) {
> +    if (FE_ICB_FILE_TYPE (File->FileEntry) == UdfFileEntrySymlink) {
>        FreePool ((VOID *)File->FileIdentifierDesc);
> 
>        FileEntry = File->FileEntry;
> @@ -1951,7 +1864,7 @@ ReadDirectoryEntry (
>      // Update FidOffset to point to next FID.
>      //
>      ReadDirInfo->FidOffset += GetFidDescriptorLength (FileIdentifierDesc);
> -  } while (IS_FID_DELETED_FILE (FileIdentifierDesc));
> +  } while (FileIdentifierDesc->FileCharacteristics & DELETED_FILE);
> 
>    DuplicateFid (FileIdentifierDesc, FoundFid);
> 
> @@ -2197,43 +2110,6 @@ Error_Find_File:
>  }
> 
>  /**
> -  Clean up in-memory UDF volume information.
> -
> -  @param[in] Volume Volume information pointer.
> -
> -**/
> -VOID
> -CleanupVolumeInformation (
> -  IN UDF_VOLUME_INFO *Volume
> -  )
> -{
> -  UINTN Index;
> -
> -  if (Volume->LogicalVolDescs != NULL) {
> -    for (Index = 0; Index < Volume->LogicalVolDescsNo; Index++) {
> -      FreePool ((VOID *)Volume->LogicalVolDescs[Index]);
> -    }
> -    FreePool ((VOID *)Volume->LogicalVolDescs);
> -  }
> -
> -  if (Volume->PartitionDescs != NULL) {
> -    for (Index = 0; Index < Volume->PartitionDescsNo; Index++) {
> -      FreePool ((VOID *)Volume->PartitionDescs[Index]);
> -    }
> -    FreePool ((VOID *)Volume->PartitionDescs);
> -  }
> -
> -  if (Volume->FileSetDescs != NULL) {
> -    for (Index = 0; Index < Volume->FileSetDescsNo; Index++) {
> -      FreePool ((VOID *)Volume->FileSetDescs[Index]);
> -    }
> -    FreePool ((VOID *)Volume->FileSetDescs);
> -  }
> -
> -  ZeroMem ((VOID *)Volume, sizeof (UDF_VOLUME_INFO));
> -}
> -
> -/**
>    Clean up in-memory UDF file information.
> 
>    @param[in] File File information pointer.
> @@ -2333,6 +2209,7 @@ SetFileInfo (
>    EFI_FILE_INFO            *FileInfo;
>    UDF_FILE_ENTRY           *FileEntry;
>    UDF_EXTENDED_FILE_ENTRY  *ExtendedFileEntry;
> +  UDF_DESCRIPTOR_TAG       *DescriptorTag;
> 
>    //
>    // Calculate the needed size for the EFI_FILE_INFO structure.
> @@ -2367,7 +2244,9 @@ SetFileInfo (
>      FileInfo->Attribute |= EFI_FILE_HIDDEN;
>    }
> 
> -  if (IS_FE (File->FileEntry)) {
> +  DescriptorTag = File->FileEntry;
> +
> +  if (UDF_TAG_ID (DescriptorTag) == UdfFileEntry) {
>      FileEntry = (UDF_FILE_ENTRY *)File->FileEntry;
> 
>      //
> @@ -2403,7 +2282,7 @@ SetFileInfo (
>                                     FileEntry->AccessTime.Second;
>      FileInfo->LastAccessTime.Nanosecond  =
>                                     FileEntry->AccessTime.HundredsOfMicroseconds;
> -  } else if (IS_EFE (File->FileEntry)) {
> +  } else if (UDF_TAG_ID (DescriptorTag) == UdfExtendedFileEntry) {
>      ExtendedFileEntry = (UDF_EXTENDED_FILE_ENTRY *)File->FileEntry;
> 
>      //
> @@ -2487,91 +2366,103 @@ GetVolumeSize (
>    OUT  UINT64                 *FreeSpaceSize
>    )
>  {
> -  UDF_EXTENT_AD                 ExtentAd;
> -  UINT32                        LogicalBlockSize;
> -  UINT64                        Lsn;
> -  EFI_STATUS                    Status;
> -  UDF_LOGICAL_VOLUME_INTEGRITY  *LogicalVolInt;
> -  UINTN                         Index;
> -  UINTN                         Length;
> -  UINT32                        LsnsNo;
> -
> -  *VolumeSize     = 0;
> -  *FreeSpaceSize  = 0;
> -
> -  for (Index = 0; Index < Volume->LogicalVolDescsNo; Index++) {
> -    CopyMem ((VOID *)&ExtentAd,
> -             (VOID *)&Volume->LogicalVolDescs[Index]->IntegritySequenceExtent,
> -             sizeof (UDF_EXTENT_AD));
> -    if (ExtentAd.ExtentLength == 0) {
> -      continue;
> -    }
> +  EFI_STATUS                     Status;
> +  UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;
> +  UDF_EXTENT_AD                  *ExtentAd;
> +  UINT64                         Lsn;
> +  UINT32                         LogicalBlockSize;
> +  UDF_LOGICAL_VOLUME_INTEGRITY   *LogicalVolInt;
> +  UDF_DESCRIPTOR_TAG             *DescriptorTag;
> +  UINTN                          Index;
> +  UINTN                          Length;
> +  UINT32                         LsnsNo;
> 
> -    LogicalBlockSize = LV_BLOCK_SIZE (Volume, Index);
> +  LogicalVolDesc = &Volume->LogicalVolDesc;
> 
> -  Read_Next_Sequence:
> -    LogicalVolInt = (UDF_LOGICAL_VOLUME_INTEGRITY *)
> -      AllocatePool (ExtentAd.ExtentLength);
> -    if (LogicalVolInt == NULL) {
> -      return EFI_OUT_OF_RESOURCES;
> -    }
> +  ExtentAd = &LogicalVolDesc->IntegritySequenceExtent;
> +
> +  if (ExtentAd->ExtentLength == 0) {
> +    return EFI_VOLUME_CORRUPTED;
> +  }
> 
> -    Lsn = (UINT64)ExtentAd.ExtentLocation;
> +  LogicalVolInt = AllocatePool (ExtentAd->ExtentLength);
> +  if (LogicalVolInt == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> 
> -    Status = DiskIo->ReadDisk (
> -      DiskIo,
> -      BlockIo->Media->MediaId,
> -      MultU64x32 (Lsn, LogicalBlockSize),
> -      ExtentAd.ExtentLength,
> -      (VOID *)LogicalVolInt
> -      );
> -    if (EFI_ERROR (Status)) {
> -      FreePool ((VOID *)LogicalVolInt);
> -      return Status;
> -    }
> +  //
> +  // Get location of Logical Volume Integrity Descriptor
> +  //
> +  Lsn = (UINT64)ExtentAd->ExtentLocation - Volume->MainVdsStartLocation;
> 
> -    if (!IS_LVID (LogicalVolInt)) {
> -      FreePool ((VOID *)LogicalVolInt);
> -      return EFI_VOLUME_CORRUPTED;
> -    }
> +  LogicalBlockSize = LogicalVolDesc->LogicalBlockSize;
> 
> -    Length = LogicalVolInt->NumberOfPartitions;
> -    for (Index = 0; Index < Length; Index += sizeof (UINT32)) {
> -      LsnsNo = *(UINT32 *)((UINT8 *)LogicalVolInt->Data + Index);
> -      if (LsnsNo == 0xFFFFFFFFUL) {
> -        //
> -        // Size not specified.
> -        //
> -        continue;
> -      }
> +  //
> +  // Read disk block
> +  //
> +  Status = DiskIo->ReadDisk (
> +    DiskIo,
> +    BlockIo->Media->MediaId,
> +    MultU64x32 (Lsn, LogicalBlockSize),
> +    ExtentAd->ExtentLength,
> +    LogicalVolInt
> +    );
> +  if (EFI_ERROR (Status)) {
> +    goto Out_Free;
> +  }
> 
> -      *FreeSpaceSize += MultU64x32 ((UINT64)LsnsNo, LogicalBlockSize);
> -    }
> +  DescriptorTag = &LogicalVolInt->DescriptorTag;
> 
> -    Length = (LogicalVolInt->NumberOfPartitions * sizeof (UINT32)) << 1;
> -    for (; Index < Length; Index += sizeof (UINT32)) {
> -      LsnsNo = *(UINT32 *)((UINT8 *)LogicalVolInt->Data + Index);
> -      if (LsnsNo == 0xFFFFFFFFUL) {
> -        //
> -        // Size not specified.
> -        //
> -        continue;
> -      }
> +  //
> +  // Check if read block is a Logical Volume Integrity Descriptor
> +  //
> +  if (UDF_TAG_ID (DescriptorTag) != UdfLogicalVolumeIntegrityDescriptor) {
> +    Status = EFI_VOLUME_CORRUPTED;
> +    goto Out_Free;
> +  }
> 
> -      *VolumeSize += MultU64x32 ((UINT64)LsnsNo, LogicalBlockSize);
> -    }
> +  *VolumeSize = 0;
> +  *FreeSpaceSize = 0;
> 
> -    CopyMem ((VOID *)&ExtentAd,(VOID *)&LogicalVolInt->NextIntegrityExtent,
> -             sizeof (UDF_EXTENT_AD));
> -    if (ExtentAd.ExtentLength > 0) {
> -      FreePool ((VOID *)LogicalVolInt);
> -      goto Read_Next_Sequence;
> +  Length = LogicalVolInt->NumberOfPartitions;
> +  for (Index = 0; Index < Length; Index += sizeof (UINT32)) {
> +    LsnsNo = *(UINT32 *)((UINT8 *)LogicalVolInt->Data + Index);
> +    //
> +    // Check if size is not specified
> +    //
> +    if (LsnsNo == 0xFFFFFFFFUL) {
> +      continue;
>      }
> +    //
> +    // Accumulate free space size
> +    //
> +    *FreeSpaceSize += MultU64x32 ((UINT64)LsnsNo, LogicalBlockSize);
> +  }
> 
> -    FreePool ((VOID *)LogicalVolInt);
> +  Length = LogicalVolInt->NumberOfPartitions * sizeof (UINT32) * 2;
> +  for (; Index < Length; Index += sizeof (UINT32)) {
> +    LsnsNo = *(UINT32 *)((UINT8 *)LogicalVolInt->Data + Index);
> +    //
> +    // Check if size is not specified
> +    //
> +    if (LsnsNo == 0xFFFFFFFFUL) {
> +      continue;
> +    }
> +    //
> +    // Accumulate used volume space
> +    //
> +    *VolumeSize += MultU64x32 ((UINT64)LsnsNo, LogicalBlockSize);
>    }
> 
> -  return EFI_SUCCESS;
> +  Status = EFI_SUCCESS;
> +
> +Out_Free:
> +  //
> +  // Free Logical Volume Integrity Descriptor
> +  //
> +  FreePool (LogicalVolInt);
> +
> +  return Status;
>  }
> 
>  /**
> diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/Udf.c
> b/MdeModulePkg/Universal/Disk/UdfDxe/Udf.c
> index 49dc7077b7..d4163b89ca 100644
> --- a/MdeModulePkg/Universal/Disk/UdfDxe/Udf.c
> +++ b/MdeModulePkg/Universal/Disk/UdfDxe/Udf.c
> @@ -276,13 +276,6 @@ UdfDriverBindingStop (
>        NULL
>        );
> 
> -    //
> -    // Check if there's any open file. If so, clean them up.
> -    //
> -    if (PrivFsData->OpenFiles > 0) {
> -      CleanupVolumeInformation (&PrivFsData->Volume);
> -    }
> -
>      FreePool ((VOID *)PrivFsData);
>    }
> 
> diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/Udf.h
> b/MdeModulePkg/Universal/Disk/UdfDxe/Udf.h
> index 44c843fd4d..ef2a3359ce 100644
> --- a/MdeModulePkg/Universal/Disk/UdfDxe/Udf.h
> +++ b/MdeModulePkg/Universal/Disk/UdfDxe/Udf.h
> @@ -49,61 +49,34 @@
>      { 0x89, 0x56, 0x73, 0xCD, 0xA3, 0x26, 0xCD, 0x0A }  \
>    }
> 
> -#define UDF_DEFAULT_LV_NUM 0
> -
> -#define IS_PVD(_Pointer) \
> -  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 1))
> -#define IS_PD(_Pointer) \
> -  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 5))
> -#define IS_LVD(_Pointer) \
> -  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 6))
> -#define IS_TD(_Pointer) \
> -  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 8))
> -#define IS_FSD(_Pointer) \
> -  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 256))
> -#define IS_FE(_Pointer) \
> -  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 261))
> -#define IS_EFE(_Pointer) \
> -  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 266))
> -#define IS_FID(_Pointer) \
> -  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 257))
> -#define IS_AED(_Pointer) \
> -  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 258))
> -#define IS_LVID(_Pointer) \
> -  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 9))
> -
> -#define _GET_FILETYPE(_Pointer) \
> -  (IS_FE (_Pointer) ? \
> -   (((UDF_FILE_ENTRY *)(_Pointer))->IcbTag.FileType) \
> -   : \
> -   (((UDF_EXTENDED_FILE_ENTRY *)(_Pointer))->IcbTag.FileType))
> -
> -#define IS_FE_DIRECTORY(_Pointer) \
> -  ((BOOLEAN)(_GET_FILETYPE (_Pointer) == 4))
> -#define IS_FE_STANDARD_FILE(_Pointer) \
> -  ((BOOLEAN)(_GET_FILETYPE (_Pointer) == 5))
> -#define IS_FE_SYMLINK(_Pointer) \
> -  ((BOOLEAN)(_GET_FILETYPE (_Pointer) == 12))
> +#define FE_ICB_FILE_TYPE(_Ptr) \
> +  (UDF_FILE_ENTRY_TYPE)( \
> +  (UDF_TAG_ID ((UDF_DESCRIPTOR_TAG *)(_Ptr)) == UdfFileEntry ? \
> +   ((UDF_FILE_ENTRY *)(_Ptr))->IcbTag.FileType : \
> +   ((UDF_EXTENDED_FILE_ENTRY *)(_Ptr))->IcbTag.FileType))
> +
> +typedef enum {
> +  UdfFileEntryDirectory = 4,
> +  UdfFileEntryStandardFile = 5,
> +  UdfFileEntrySymlink = 12,
> +} UDF_FILE_ENTRY_TYPE;
> 
>  #define HIDDEN_FILE     (1 << 0)
>  #define DIRECTORY_FILE  (1 << 1)
>  #define DELETED_FILE    (1 << 2)
>  #define PARENT_FILE     (1 << 3)
> 
> -#define _GET_FILE_CHARS(_Pointer) \
> -  (((UDF_FILE_IDENTIFIER_DESCRIPTOR *)(_Pointer))->FileCharacteristics)
> -
> -#define IS_FID_HIDDEN_FILE(_Pointer) \
> -  ((BOOLEAN)(_GET_FILE_CHARS (_Pointer) & HIDDEN_FILE))
> -#define IS_FID_DIRECTORY_FILE(_Pointer) \
> -  ((BOOLEAN)(_GET_FILE_CHARS (_Pointer) & DIRECTORY_FILE))
> -#define IS_FID_DELETED_FILE(_Pointer) \
> -  ((BOOLEAN)(_GET_FILE_CHARS (_Pointer) & DELETED_FILE))
> -#define IS_FID_PARENT_FILE(_Pointer) \
> -  ((BOOLEAN)(_GET_FILE_CHARS (_Pointer) & PARENT_FILE))
> -#define IS_FID_NORMAL_FILE(_Pointer) \
> -  ((BOOLEAN)(!IS_FID_DIRECTORY_FILE (_Pointer) && \
> -         !IS_FID_PARENT_FILE (_Pointer)))
> +#define IS_FID_HIDDEN_FILE(_Fid) \
> +  (BOOLEAN)((_Fid)->FileCharacteristics & HIDDEN_FILE)
> +#define IS_FID_DIRECTORY_FILE(_Fid) \
> +  (BOOLEAN)((_Fid)->FileCharacteristics & DIRECTORY_FILE)
> +#define IS_FID_DELETED_FILE(_Fid) \
> +  (BOOLEAN)((_Fid)->FileCharacteristics & DELETED_FILE)
> +#define IS_FID_PARENT_FILE(_Fid) \
> +  (BOOLEAN)((_Fid)->FileCharacteristics & PARENT_FILE)
> +#define IS_FID_NORMAL_FILE(_Fid) \
> +  (BOOLEAN)(!IS_FID_DIRECTORY_FILE (_Fid) && \
> +            !IS_FID_PARENT_FILE (_Fid))
> 
>  typedef enum {
>    ShortAdsSequence,
> @@ -152,14 +125,8 @@ typedef enum {
>  #define IS_VALID_COMPRESSION_ID(_CompId) \
>    ((BOOLEAN)((_CompId) == 8 || (_CompId) == 16))
> 
> -#define LV_BLOCK_SIZE(_Vol, _LvNum) \
> -  (_Vol)->LogicalVolDescs[(_LvNum)]->LogicalBlockSize
> -
>  #define UDF_STANDARD_IDENTIFIER_LENGTH   5
> 
> -#define LV_UDF_REVISION(_Lv) \
> -  *(UINT16 *)(UINTN)(_Lv)->DomainIdentifier.IdentifierSuffix
> -
>  #pragma pack(1)
> 
>  typedef struct {
> @@ -186,17 +153,6 @@ typedef struct {
>  #pragma pack(1)
> 
>  typedef struct {
> -  UINT8           CharacterSetType;
> -  UINT8           CharacterSetInfo[63];
> -} UDF_CHAR_SPEC;
> -
> -typedef struct {
> -  UINT8           Flags;
> -  UINT8           Identifier[23];
> -  UINT8           IdentifierSuffix[8];
> -} UDF_ENTITY_ID;
> -
> -typedef struct {
>    UINT16          TypeAndTimezone;
>    INT16           Year;
>    UINT8           Month;
> @@ -210,17 +166,6 @@ typedef struct {
>  } UDF_TIMESTAMP;
> 
>  typedef struct {
> -  UINT32        LogicalBlockNumber;
> -  UINT16        PartitionReferenceNumber;
> -} UDF_LB_ADDR;
> -
> -typedef struct {
> -  UINT32                           ExtentLength;
> -  UDF_LB_ADDR                      ExtentLocation;
> -  UINT8                            ImplementationUse[6];
> -} UDF_LONG_ALLOCATION_DESCRIPTOR;
> -
> -typedef struct {
>    UDF_DESCRIPTOR_TAG                 DescriptorTag;
>    UINT32                             PrevAllocationExtentDescriptor;
>    UINT32                             LengthOfAllocationDescriptors;
> @@ -235,6 +180,17 @@ typedef struct {
>  } UDF_VOLUME_DESCRIPTOR;
> 
>  typedef struct {
> +  UDF_DESCRIPTOR_TAG             DescriptorTag;
> +  UDF_TIMESTAMP                  RecordingDateTime;
> +  UINT32                         IntegrityType;
> +  UDF_EXTENT_AD                  NextIntegrityExtent;
> +  UINT8                          LogicalVolumeContentsUse[32];
> +  UINT32                         NumberOfPartitions;
> +  UINT32                         LengthOfImplementationUse;
> +  UINT8                          Data[0];
> +} UDF_LOGICAL_VOLUME_INTEGRITY;
> +
> +typedef struct {
>    UDF_DESCRIPTOR_TAG         DescriptorTag;
>    UINT32                     VolumeDescriptorSequenceNumber;
>    UINT16                     PartitionFlags;
> @@ -251,33 +207,6 @@ typedef struct {
> 
>  typedef struct {
>    UDF_DESCRIPTOR_TAG              DescriptorTag;
> -  UINT32                          VolumeDescriptorSequenceNumber;
> -  UDF_CHAR_SPEC                   DescriptorCharacterSet;
> -  UINT8                           LogicalVolumeIdentifier[128];
> -  UINT32                          LogicalBlockSize;
> -  UDF_ENTITY_ID                   DomainIdentifier;
> -  UDF_LONG_ALLOCATION_DESCRIPTOR  LogicalVolumeContentsUse;
> -  UINT32                          MapTableLength;
> -  UINT32                          NumberOfPartitionMaps;
> -  UDF_ENTITY_ID                   ImplementationIdentifier;
> -  UINT8                           ImplementationUse[128];
> -  UDF_EXTENT_AD                   IntegritySequenceExtent;
> -  UINT8                           PartitionMaps[6];
> -} UDF_LOGICAL_VOLUME_DESCRIPTOR;
> -
> -typedef struct {
> -  UDF_DESCRIPTOR_TAG             DescriptorTag;
> -  UDF_TIMESTAMP                  RecordingDateTime;
> -  UINT32                         IntegrityType;
> -  UDF_EXTENT_AD                  NextIntegrityExtent;
> -  UINT8                          LogicalVolumeContentsUse[32];
> -  UINT32                         NumberOfPartitions;
> -  UINT32                         LengthOfImplementationUse;
> -  UINT8                          Data[0];
> -} UDF_LOGICAL_VOLUME_INTEGRITY;
> -
> -typedef struct {
> -  UDF_DESCRIPTOR_TAG              DescriptorTag;
>    UDF_TIMESTAMP                   RecordingDateAndTime;
>    UINT16                          InterchangeLevel;
>    UINT16                          MaximumInterchangeLevel;
> @@ -389,12 +318,10 @@ typedef struct {
>  // UDF filesystem driver's private data
>  //
>  typedef struct {
> -  UDF_LOGICAL_VOLUME_DESCRIPTOR  **LogicalVolDescs;
> -  UINTN                          LogicalVolDescsNo;
> -  UDF_PARTITION_DESCRIPTOR       **PartitionDescs;
> -  UINTN                          PartitionDescsNo;
> -  UDF_FILE_SET_DESCRIPTOR        **FileSetDescs;
> -  UINTN                          FileSetDescsNo;
> +  UINT64                         MainVdsStartLocation;
> +  UDF_LOGICAL_VOLUME_DESCRIPTOR  LogicalVolDesc;
> +  UDF_PARTITION_DESCRIPTOR       PartitionDesc;
> +  UDF_FILE_SET_DESCRIPTOR        FileSetDesc;
>    UINTN                          FileEntrySize;
>  } UDF_VOLUME_INFO;
> 
> @@ -884,17 +811,6 @@ ResolveSymlink (
>    );
> 
>  /**
> -  Clean up in-memory UDF volume information.
> -
> -  @param[in] Volume Volume information pointer.
> -
> -**/
> -VOID
> -CleanupVolumeInformation (
> -  IN UDF_VOLUME_INFO *Volume
> -  );
> -
> -/**
>    Clean up in-memory UDF file information.
> 
>    @param[in] File File information pointer.
> --
> 2.11.0
> 
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Re: [edk2] [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix creation of UDF logical partition
Posted by Zeng, Star 7 years, 3 months ago
VS2015 Build-tested-by: Star Zeng <star.zeng@intel.com>

I have a minor comment to this patch title, how about to use "MdeModulePkg/UDF: Fix creation of UDF logical partition" as this patch is touching both PartitionDxe and UdfDxe? Otherwise, you'd better to split this patch to two, one for PartitionDxe and one for UdfDxe.

Since the patch could fix the issue we found, and if you agree my minor comment above, Reviewed-by: Star Zeng <star.zeng@intel.com>


Thanks,
Star
-----Original Message-----
From: Wu, Hao A 
Sent: Thursday, September 21, 2017 4:09 PM
To: Paulo Alcantara <pcacjr@zytor.com>; edk2-devel@lists.01.org
Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Laszlo Ersek <lersek@redhat.com>; Dong, Eric <eric.dong@intel.com>; Zeng, Star <star.zeng@intel.com>
Subject: RE: [edk2] [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix creation of UDF logical partition

I did a simple test on a Windows8.1 installation DVD, and here's the result
of a map command under shell:

Before the patch:
Mapping table
      FS0: Alias(s):CD0f65535a1:;BLK2:
          PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x5,0xFFFF,0x0)/CDROM(0x1)
     BLK0: Alias(s):
          PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x5,0xFFFF,0x0)
     BLK1: Alias(s):
          PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x5,0xFFFF,0x0)/CDROM(0x0)
      FS1: Alias(s):CD0f65535ab:;BLK5:
          PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x5,0xFFFF,0x0)/VenMedia(C5BD4D42-1A76-4996-8956-73CDA326CD0A)/CDROM(0x1)
     BLK3: Alias(s):
          PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x5,0xFFFF,0x0)/VenMedia(C5BD4D42-1A76-4996-8956-73CDA326CD0A)
     BLK4: Alias(s):
          PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x5,0xFFFF,0x0)/VenMedia(C5BD4D42-1A76-4996-8956-73CDA326CD0A)/CDROM(0x0)

After the patch:
Mapping table
      FS0: Alias(s):CD0f65535a1:;BLK2:
          PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x5,0xFFFF,0x0)/CDROM(0x1)
     BLK0: Alias(s):
          PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x5,0xFFFF,0x0)
     BLK1: Alias(s):
          PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x5,0xFFFF,0x0)/CDROM(0x0)
     BLK3: Alias(s):
          PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x5,0xFFFF,0x0)/VenMedia(C5BD4D42-1A76-4996-8956-73CDA326CD0A)


Since the additional file system is gone:
Tested-by: Hao Wu <hao.a.wu@intel.com>


Best Regards,
Hao Wu

> -----Original Message-----
> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of Paulo
> Alcantara
> Sent: Thursday, September 21, 2017 2:16 AM
> To: edk2-devel@lists.01.org
> Cc: Ni, Ruiyu; Laszlo Ersek; Dong, Eric; Zeng, Star
> Subject: [edk2] [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix creation of
> UDF logical partition
> 
> Do not reserve entire block device size for an UDF file system -
> instead, reserve the appropriate space (UDF logical volume space) for
> it.
> 
> Additionally, only create a logical partition for UDF logical volumes
> that are currently supported by EDK2 UDF file system implementation. For
> instance, an UDF volume with a single LVD and a single Physical (Type 1)
> Partition will be supported.
> 
> Cc: Eric Dong <eric.dong@intel.com>
> Cc: Ruiyu Ni <ruiyu.ni@intel.com>
> Cc: Star Zeng <star.zeng@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Reported-by: Ruiyu Ni <ruiyu.ni@intel.com>
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Paulo Alcantara <pcacjr@zytor.com>
> ---
>  MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c            | 363 ++++++++++--
>  MdeModulePkg/Universal/Disk/UdfDxe/File.c                 |  16 +-
>  MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c | 627
> ++++++++------------
>  MdeModulePkg/Universal/Disk/UdfDxe/Udf.c                  |   7 -
>  MdeModulePkg/Universal/Disk/UdfDxe/Udf.h                  | 158 ++---
>  5 files changed, 606 insertions(+), 565 deletions(-)
> 
> diff --git a/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
> b/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
> index 609f56cef6..572ba7a81a 100644
> --- a/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
> +++ b/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
> @@ -64,11 +64,12 @@ FindAnchorVolumeDescriptorPointer (
>    OUT  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint
>    )
>  {
> -  EFI_STATUS  Status;
> -  UINT32      BlockSize;
> -  EFI_LBA     EndLBA;
> -  EFI_LBA     DescriptorLBAs[4];
> -  UINTN       Index;
> +  EFI_STATUS          Status;
> +  UINT32              BlockSize;
> +  EFI_LBA             EndLBA;
> +  EFI_LBA             DescriptorLBAs[4];
> +  UINTN               Index;
> +  UDF_DESCRIPTOR_TAG  *DescriptorTag;
> 
>    BlockSize = BlockIo->Media->BlockSize;
>    EndLBA = BlockIo->Media->LastBlock;
> @@ -88,10 +89,13 @@ FindAnchorVolumeDescriptorPointer (
>      if (EFI_ERROR (Status)) {
>        return Status;
>      }
> +
> +    DescriptorTag = &AnchorPoint->DescriptorTag;
> +
>      //
>      // Check if read LBA has a valid AVDP descriptor.
>      //
> -    if (IS_AVDP (AnchorPoint)) {
> +    if (DescriptorTag->TagIdentifier == UdfAnchorVolumeDescriptorPointer) {
>        return EFI_SUCCESS;
>      }
>    }
> @@ -102,23 +106,18 @@ FindAnchorVolumeDescriptorPointer (
>  }
> 
>  /**
> -  Check if block device supports a valid UDF file system as specified by OSTA
> -  Universal Disk Format Specification 2.60.
> +  Find UDF volume identifiers in a Volume Recognition Sequence.
> 
> -  @param[in]   BlockIo  BlockIo interface.
> -  @param[in]   DiskIo   DiskIo interface.
> +  @param[in]  BlockIo             BlockIo interface.
> +  @param[in]  DiskIo              DiskIo interface.
> 
> -  @retval EFI_SUCCESS          UDF file system found.
> -  @retval EFI_UNSUPPORTED      UDF file system not found.
> -  @retval EFI_NO_MEDIA         The device has no media.
> -  @retval EFI_DEVICE_ERROR     The device reported an error.
> -  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
> -  @retval EFI_OUT_OF_RESOURCES The scan was not successful due to lack of
> -                               resources.
> +  @retval EFI_SUCCESS             UDF volume identifiers were found.
> +  @retval EFI_NOT_FOUND           UDF volume identifiers were not found.
> +  @retval other                   Failed to perform disk I/O.
> 
>  **/
>  EFI_STATUS
> -SupportUdfFileSystem (
> +FindUdfVolumeIdentifiers (
>    IN EFI_BLOCK_IO_PROTOCOL  *BlockIo,
>    IN EFI_DISK_IO_PROTOCOL   *DiskIo
>    )
> @@ -128,7 +127,6 @@ SupportUdfFileSystem (
>    UINT64                                EndDiskOffset;
>    CDROM_VOLUME_DESCRIPTOR               VolDescriptor;
>    CDROM_VOLUME_DESCRIPTOR               TerminatingVolDescriptor;
> -  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  AnchorPoint;
> 
>    ZeroMem ((VOID *)&TerminatingVolDescriptor, sizeof
> (CDROM_VOLUME_DESCRIPTOR));
> 
> @@ -167,7 +165,7 @@ SupportUdfFileSystem (
>          (CompareMem ((VOID *)&VolDescriptor,
>                       (VOID *)&TerminatingVolDescriptor,
>                       sizeof (CDROM_VOLUME_DESCRIPTOR)) == 0)) {
> -      return EFI_UNSUPPORTED;
> +      return EFI_NOT_FOUND;
>      }
>    }
> 
> @@ -176,7 +174,7 @@ SupportUdfFileSystem (
>    //
>    Offset += UDF_LOGICAL_SECTOR_SIZE;
>    if (Offset >= EndDiskOffset) {
> -    return EFI_UNSUPPORTED;
> +    return EFI_NOT_FOUND;
>    }
> 
>    Status = DiskIo->ReadDisk (
> @@ -196,7 +194,7 @@ SupportUdfFileSystem (
>        (CompareMem ((VOID *)VolDescriptor.Unknown.Id,
>                     (VOID *)UDF_NSR3_IDENTIFIER,
>                     sizeof (VolDescriptor.Unknown.Id)) != 0)) {
> -    return EFI_UNSUPPORTED;
> +    return EFI_NOT_FOUND;
>    }
> 
>    //
> @@ -204,7 +202,7 @@ SupportUdfFileSystem (
>    //
>    Offset += UDF_LOGICAL_SECTOR_SIZE;
>    if (Offset >= EndDiskOffset) {
> -    return EFI_UNSUPPORTED;
> +    return EFI_NOT_FOUND;
>    }
> 
>    Status = DiskIo->ReadDisk (
> @@ -221,15 +219,291 @@ SupportUdfFileSystem (
>    if (CompareMem ((VOID *)VolDescriptor.Unknown.Id,
>                    (VOID *)UDF_TEA_IDENTIFIER,
>                    sizeof (VolDescriptor.Unknown.Id)) != 0) {
> -    return EFI_UNSUPPORTED;
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Check if Logical Volume Descriptor is supported by current EDK2 UDF file
> +  system implementation.
> +
> +  @param[in]  LogicalVolDesc  Logical Volume Descriptor pointer.
> +
> +  @retval TRUE                Logical Volume Descriptor is supported.
> +  @retval FALSE               Logical Volume Descriptor is not supported.
> +
> +**/
> +BOOLEAN
> +IsLogicalVolumeDescriptorSupported (
> +  UDF_LOGICAL_VOLUME_DESCRIPTOR *LogicalVolDesc
> +  )
> +{
> +  //
> +  // Check for a valid UDF revision range
> +  //
> +  switch (UDF_LVD_REVISION (LogicalVolDesc)) {
> +  case 0x0102:
> +  case 0x0150:
> +  case 0x0200:
> +  case 0x0201:
> +  case 0x0250:
> +  case 0x0260:
> +    break;
> +  default:
> +    return FALSE;
> +  }
> +
> +  //
> +  // Check for a single Partition Map
> +  //
> +  if (LogicalVolDesc->NumberOfPartitionMaps > 1) {
> +    return FALSE;
> +  }
> +  //
> +  // UDF 1.02 revision supports only Type 1 (Physical) partitions, but
> +  // let's check it any way.
> +  //
> +  // PartitionMap[0] -> type
> +  // PartitionMap[1] -> length (in bytes)
> +  //
> +  if (LogicalVolDesc->PartitionMaps[0] != 1 ||
> +      LogicalVolDesc->PartitionMaps[1] != 6) {
> +    return FALSE;
> +  }
> +
> +  return TRUE;
> +}
> +
> +/**
> +  Find UDF logical volume location and whether it is supported by current
> EDK2
> +  UDF file system implementation.
> +
> +  @param[in]  BlockIo             BlockIo interface.
> +  @param[in]  DiskIo              DiskIo interface.
> +  @param[in]  AnchorPoint         Anchor volume descriptor pointer.
> +  @param[out] MainVdsStartBlock   Main VDS starting block number.
> +  @param[out] MainVdsEndBlock     Main VDS ending block number.
> +
> +  @retval EFI_SUCCESS             UDF logical volume was found.
> +  @retval EFI_VOLUME_CORRUPTED    UDF file system structures are
> corrupted.
> +  @retval EFI_UNSUPPORTED         UDF logical volume is not supported.
> +  @retval other                   Failed to perform disk I/O.
> +
> +**/
> +EFI_STATUS
> +FindLogicalVolumeLocation (
> +  IN   EFI_BLOCK_IO_PROTOCOL                 *BlockIo,
> +  IN   EFI_DISK_IO_PROTOCOL                  *DiskIo,
> +  IN   UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint,
> +  OUT  UINT64                                *MainVdsStartBlock,
> +  OUT  UINT64                                *MainVdsEndBlock
> +  )
> +{
> +  EFI_STATUS                     Status;
> +  UINT32                         BlockSize;
> +  EFI_LBA                        LastBlock;
> +  UDF_EXTENT_AD                  *ExtentAd;
> +  UINT64                         SeqBlocksNum;
> +  UINT64                         SeqStartBlock;
> +  UINT64                         GuardMainVdsStartBlock;
> +  VOID                           *Buffer;
> +  UINT64                         SeqEndBlock;
> +  BOOLEAN                        StopSequence;
> +  UINTN                          LvdsCount;
> +  UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;
> +  UDF_DESCRIPTOR_TAG             *DescriptorTag;
> +
> +  BlockSize = BlockIo->Media->BlockSize;
> +  LastBlock = BlockIo->Media->LastBlock;
> +  ExtentAd = &AnchorPoint->MainVolumeDescriptorSequenceExtent;
> +
> +  //
> +  // UDF 2.60, 2.2.3.1 struct MainVolumeDescriptorSequenceExtent
> +  //
> +  // The Main Volume Descriptor Sequence Extent shall have a minimum
> length of
> +  // 16 logical sectors.
> +  //
> +  // Also make sure it does not exceed maximum number of blocks in the disk.
> +  //
> +  SeqBlocksNum = DivU64x32 ((UINT64)ExtentAd->ExtentLength, BlockSize);
> +  if (SeqBlocksNum < 16 || (EFI_LBA)SeqBlocksNum > LastBlock + 1) {
> +    return EFI_VOLUME_CORRUPTED;
> +  }
> +
> +  //
> +  // Check for valid Volume Descriptor Sequence starting block number
> +  //
> +  SeqStartBlock = (UINT64)ExtentAd->ExtentLocation;
> +  if (SeqStartBlock > LastBlock ||
> +      SeqStartBlock + SeqBlocksNum - 1 > LastBlock) {
> +    return EFI_VOLUME_CORRUPTED;
>    }
> 
> +  GuardMainVdsStartBlock = SeqStartBlock;
> +
> +  //
> +  // Allocate buffer for reading disk blocks
> +  //
> +  Buffer = AllocateZeroPool ((UINTN)BlockSize);
> +  if (Buffer == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  SeqEndBlock = SeqStartBlock + SeqBlocksNum;
> +  StopSequence = FALSE;
> +  LvdsCount = 0;
> +  Status = EFI_VOLUME_CORRUPTED;
> +  //
> +  // Start Main Volume Descriptor Sequence
> +  //
> +  for (; SeqStartBlock < SeqEndBlock && !StopSequence; SeqStartBlock++) {
> +    //
> +    // Read disk block
> +    //
> +    Status = BlockIo->ReadBlocks (
> +      BlockIo,
> +      BlockIo->Media->MediaId,
> +      SeqStartBlock,
> +      BlockSize,
> +      Buffer
> +      );
> +    if (EFI_ERROR (Status)) {
> +      goto Out_Free;
> +    }
> +
> +    DescriptorTag = Buffer;
> +
> +    //
> +    // ECMA 167, 8.4.1 Contents of a Volume Descriptor Sequence
> +    //
> +    // - A Volume Descriptor Sequence shall contain one or more Primary
> Volume
> +    //   Descriptors.
> +    // - A Volume Descriptor Sequence shall contain zero or more
> Implementation
> +    //   Use Volume Descriptors.
> +    // - A Volume Descriptor Sequence shall contain zero or more Partition
> +    //   Descriptors.
> +    // - A Volume Descriptor Sequence shall contain zero or more Logical
> Volume
> +    //   Descriptors.
> +    // - A Volume Descriptor Sequence shall contain zero or more Unallocated
> +    //   Space Descriptors.
> +    //
> +    switch (UDF_TAG_ID (DescriptorTag)) {
> +    case UdfPrimaryVolumeDescriptor:
> +    case UdfImplemenationUseVolumeDescriptor:
> +    case UdfPartitionDescriptor:
> +    case UdfUnallocatedSpaceDescriptor:
> +      break;
> +
> +    case UdfLogicalVolumeDescriptor:
> +      LogicalVolDesc = Buffer;
> +
> +      //
> +      // Check for existence of a single LVD and whether it is supported by
> +      // current EDK2 UDF file system implementation.
> +      //
> +      if (++LvdsCount > 1 ||
> +          !IsLogicalVolumeDescriptorSupported (LogicalVolDesc)) {
> +        Status = EFI_UNSUPPORTED;
> +        StopSequence = TRUE;
> +      }
> +
> +      break;
> +
> +    case UdfTerminatingDescriptor:
> +      //
> +      // Stop the sequence when we find a Terminating Descriptor
> +      // (aka Unallocated Sector), se we don't have to walk all the unallocated
> +      // area unnecessarily.
> +      //
> +      StopSequence = TRUE;
> +      break;
> +
> +    default:
> +      //
> +      // An invalid Volume Descriptor has been found in the sequece. Volume is
> +      // corrupted.
> +      //
> +      Status = EFI_VOLUME_CORRUPTED;
> +      goto Out_Free;
> +    }
> +  }
> +
> +  //
> +  // Check if LVD was found
> +  //
> +  if (!EFI_ERROR (Status) && LvdsCount == 1) {
> +    *MainVdsStartBlock = GuardMainVdsStartBlock;
> +    //
> +    // We do not need to read either LVD or PD descriptors to know the last
> +    // valid block in the found UDF file system. It's already LastBlock.
> +    //
> +    *MainVdsEndBlock = LastBlock;
> +
> +    Status = EFI_SUCCESS;
> +  }
> +
> +Out_Free:
> +  //
> +  // Free block read buffer
> +  //
> +  FreePool (Buffer);
> +
> +  return Status;
> +}
> +
> +/**
> +  Find a supported UDF file system in block device.
> +
> +  @param[in]  BlockIo             BlockIo interface.
> +  @param[in]  DiskIo              DiskIo interface.
> +  @param[out] StartingLBA         UDF file system starting LBA.
> +  @param[out] EndingLBA           UDF file system starting LBA.
> +
> +  @retval EFI_SUCCESS             UDF file system was found.
> +  @retval other                   UDF file system was not found.
> +
> +**/
> +EFI_STATUS
> +FindUdfFileSystem (
> +  IN EFI_BLOCK_IO_PROTOCOL  *BlockIo,
> +  IN EFI_DISK_IO_PROTOCOL   *DiskIo,
> +  OUT EFI_LBA               *StartingLBA,
> +  OUT EFI_LBA               *EndingLBA
> +  )
> +{
> +  EFI_STATUS Status;
> +  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  AnchorPoint;
> +
> +  //
> +  // Find UDF volume identifiers
> +  //
> +  Status = FindUdfVolumeIdentifiers (BlockIo, DiskIo);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Find Anchor Volume Descriptor Pointer
> +  //
>    Status = FindAnchorVolumeDescriptorPointer (BlockIo, DiskIo, &AnchorPoint);
>    if (EFI_ERROR (Status)) {
> -    return EFI_UNSUPPORTED;
> +    return Status;
>    }
> 
> -  return EFI_SUCCESS;
> +  //
> +  // Find Logical Volume location
> +  //
> +  Status = FindLogicalVolumeLocation (
> +    BlockIo,
> +    DiskIo,
> +    &AnchorPoint,
> +    (UINT64 *)StartingLBA,
> +    (UINT64 *)EndingLBA
> +    );
> +
> +  return Status;
>  }
> 
>  /**
> @@ -263,9 +537,9 @@ PartitionInstallUdfChildHandles (
>    UINT32                       RemainderByMediaBlockSize;
>    EFI_STATUS                   Status;
>    EFI_BLOCK_IO_MEDIA           *Media;
> -  EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode;
> -  EFI_GUID                     *VendorDefinedGuid;
>    EFI_PARTITION_INFO_PROTOCOL  PartitionInfo;
> +  EFI_LBA                      StartingLBA;
> +  EFI_LBA                      EndingLBA;
> 
>    Media = BlockIo->Media;
> 
> @@ -281,35 +555,10 @@ PartitionInstallUdfChildHandles (
>      return EFI_NOT_FOUND;
>    }
> 
> -  DevicePathNode = DevicePath;
> -  while (!IsDevicePathEnd (DevicePathNode)) {
> -    //
> -    // Do not allow checking for UDF file systems in CDROM "El Torito"
> -    // partitions, and skip duplicate installation of UDF file system child
> -    // nodes.
> -    //
> -    if (DevicePathType (DevicePathNode) == MEDIA_DEVICE_PATH) {
> -      if (DevicePathSubType (DevicePathNode) == MEDIA_CDROM_DP) {
> -        return EFI_NOT_FOUND;
> -      }
> -      if (DevicePathSubType (DevicePathNode) == MEDIA_VENDOR_DP) {
> -        VendorDefinedGuid = (EFI_GUID *)((UINTN)DevicePathNode +
> -                                         OFFSET_OF (VENDOR_DEVICE_PATH, Guid));
> -        if (CompareGuid (VendorDefinedGuid, &gUdfDevPathGuid)) {
> -          return EFI_NOT_FOUND;
> -        }
> -      }
> -    }
> -    //
> -    // Try next device path node
> -    //
> -    DevicePathNode = NextDevicePathNode (DevicePathNode);
> -  }
> -
>    //
> -  // Check if block device supports an UDF file system
> +  // Search for an UDF file system on block device
>    //
> -  Status = SupportUdfFileSystem (BlockIo, DiskIo);
> +  Status = FindUdfFileSystem (BlockIo, DiskIo, &StartingLBA, &EndingLBA);
>    if (EFI_ERROR (Status)) {
>      return EFI_NOT_FOUND;
>    }
> @@ -334,8 +583,8 @@ PartitionInstallUdfChildHandles (
>      DevicePath,
>      (EFI_DEVICE_PATH_PROTOCOL *)&gUdfDevicePath,
>      &PartitionInfo,
> -    0,
> -    Media->LastBlock,
> +    StartingLBA,
> +    EndingLBA,
>      Media->BlockSize
>      );
>    if (!EFI_ERROR (Status)) {
> diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/File.c
> b/MdeModulePkg/Universal/Disk/UdfDxe/File.c
> index 625f2c5637..6f07bf2066 100644
> --- a/MdeModulePkg/Universal/Disk/UdfDxe/File.c
> +++ b/MdeModulePkg/Universal/Disk/UdfDxe/File.c
> @@ -131,7 +131,6 @@ Error_Alloc_Priv_File_Data:
>    CleanupFileInformation (&PrivFsData->Root);
> 
>  Error_Find_Root_Dir:
> -  CleanupVolumeInformation (&PrivFsData->Volume);
> 
>  Error_Read_Udf_Volume:
>  Error_Invalid_Params:
> @@ -429,7 +428,7 @@ UdfRead (
>      }
>      ASSERT (NewFileEntryData != NULL);
> 
> -    if (IS_FE_SYMLINK (NewFileEntryData)) {
> +    if (FE_ICB_FILE_TYPE (NewFileEntryData) == UdfFileEntrySymlink) {
>        Status = ResolveSymlink (
>          BlockIo,
>          DiskIo,
> @@ -529,7 +528,6 @@ UdfClose (
>    EFI_TPL                     OldTpl;
>    EFI_STATUS                  Status;
>    PRIVATE_UDF_FILE_DATA       *PrivFileData;
> -  PRIVATE_UDF_SIMPLE_FS_DATA  *PrivFsData;
> 
>    OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
> 
> @@ -542,8 +540,6 @@ UdfClose (
> 
>    PrivFileData = PRIVATE_UDF_FILE_DATA_FROM_THIS (This);
> 
> -  PrivFsData = PRIVATE_UDF_SIMPLE_FS_DATA_FROM_THIS (PrivFileData-
> >SimpleFs);
> -
>    if (!PrivFileData->IsRootDirectory) {
>      CleanupFileInformation (&PrivFileData->File);
> 
> @@ -552,10 +548,6 @@ UdfClose (
>      }
>    }
> 
> -  if (--PrivFsData->OpenFiles == 0) {
> -    CleanupVolumeInformation (&PrivFsData->Volume);
> -  }
> -
>    FreePool ((VOID *)PrivFileData);
> 
>  Exit:
> @@ -652,7 +644,7 @@ UdfGetPosition (
>    // As per UEFI spec, if the file handle is a directory, then the current file
>    // position has no meaning and the operation is not supported.
>    //
> -  if (IS_FID_DIRECTORY_FILE (&PrivFileData->File.FileIdentifierDesc)) {
> +  if (IS_FID_DIRECTORY_FILE (PrivFileData->File.FileIdentifierDesc)) {
>      return  EFI_UNSUPPORTED;
>    }
> 
> @@ -788,7 +780,7 @@ UdfGetInfo (
>    } else if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {
>      String = VolumeLabel;
> 
> -    FileSetDesc = PrivFsData->Volume.FileSetDescs[0];
> +    FileSetDesc = &PrivFsData->Volume.FileSetDesc;
> 
>      OstaCompressed = &FileSetDesc->LogicalVolumeIdentifier[0];
> 
> @@ -847,7 +839,7 @@ UdfGetInfo (
>      FileSystemInfo->Size        = FileSystemInfoLength;
>      FileSystemInfo->ReadOnly    = TRUE;
>      FileSystemInfo->BlockSize   =
> -      LV_BLOCK_SIZE (&PrivFsData->Volume, UDF_DEFAULT_LV_NUM);
> +      PrivFsData->Volume.LogicalVolDesc.LogicalBlockSize;
>      FileSystemInfo->VolumeSize  = VolumeSize;
>      FileSystemInfo->FreeSpace   = FreeSpaceSize;
> 
> diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
> b/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
> index 5df267761f..62d817989f 100644
> --- a/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
> +++ b/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
> @@ -38,11 +38,12 @@ FindAnchorVolumeDescriptorPointer (
>    OUT  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint
>    )
>  {
> -  EFI_STATUS  Status;
> -  UINT32      BlockSize;
> -  EFI_LBA     EndLBA;
> -  EFI_LBA     DescriptorLBAs[4];
> -  UINTN       Index;
> +  EFI_STATUS          Status;
> +  UINT32              BlockSize;
> +  EFI_LBA             EndLBA;
> +  EFI_LBA             DescriptorLBAs[4];
> +  UINTN               Index;
> +  UDF_DESCRIPTOR_TAG  *DescriptorTag;
> 
>    BlockSize = BlockIo->Media->BlockSize;
>    EndLBA = BlockIo->Media->LastBlock;
> @@ -62,10 +63,13 @@ FindAnchorVolumeDescriptorPointer (
>      if (EFI_ERROR (Status)) {
>        return Status;
>      }
> +
> +    DescriptorTag = &AnchorPoint->DescriptorTag;
> +
>      //
>      // Check if read LBA has a valid AVDP descriptor.
>      //
> -    if (IS_AVDP (AnchorPoint)) {
> +    if (DescriptorTag->TagIdentifier == UdfAnchorVolumeDescriptorPointer) {
>        return EFI_SUCCESS;
>      }
>    }
> @@ -99,148 +103,98 @@ StartMainVolumeDescriptorSequence (
>    OUT  UDF_VOLUME_INFO                       *Volume
>    )
>  {
> -  EFI_STATUS                     Status;
> -  UINT32                         BlockSize;
> -  UDF_EXTENT_AD                  *ExtentAd;
> -  UINT64                         StartingLsn;
> -  UINT64                         EndingLsn;
> -  VOID                           *Buffer;
> -  UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;
> -  UDF_PARTITION_DESCRIPTOR       *PartitionDesc;
> -  UINTN                          Index;
> -  UINT32                         LogicalBlockSize;
> +  EFI_STATUS            Status;
> +  UINT32                BlockSize;
> +  UDF_EXTENT_AD         *ExtentAd;
> +  EFI_LBA               SeqStartBlock;
> +  EFI_LBA               SeqEndBlock;
> +  BOOLEAN               StopSequence;
> +  VOID                  *Buffer;
> +  UDF_DESCRIPTOR_TAG    *DescriptorTag;
> +  UINT32                LogicalBlockSize;
> +
> +  BlockSize = BlockIo->Media->BlockSize;
> +  ExtentAd = &AnchorPoint->MainVolumeDescriptorSequenceExtent;
> 
>    //
> -  // We've already found an ADVP on the volume. It contains the extent
> -  // (MainVolumeDescriptorSequenceExtent) where the Main Volume
> Descriptor
> -  // Sequence starts. Therefore, we'll look for Logical Volume Descriptors and
> -  // Partitions Descriptors and save them in memory, accordingly.
> -  //
> -  // Note also that each descriptor will be aligned on a block size (BlockSize)
> -  // boundary, so we need to read one block at a time.
> +  // Allocate buffer for reading disk blocks
>    //
> -  BlockSize    = BlockIo->Media->BlockSize;
> -  ExtentAd     = &AnchorPoint->MainVolumeDescriptorSequenceExtent;
> -  StartingLsn  = (UINT64)ExtentAd->ExtentLocation;
> -  EndingLsn    = StartingLsn + DivU64x32 (
> -                                     (UINT64)ExtentAd->ExtentLength,
> -                                     BlockSize
> -                                     );
> -
> -  Volume->LogicalVolDescs =
> -    (UDF_LOGICAL_VOLUME_DESCRIPTOR **)AllocateZeroPool (ExtentAd-
> >ExtentLength);
> -  if (Volume->LogicalVolDescs == NULL) {
> -    return EFI_OUT_OF_RESOURCES;
> -  }
> -
> -  Volume->PartitionDescs =
> -    (UDF_PARTITION_DESCRIPTOR **)AllocateZeroPool (ExtentAd-
> >ExtentLength);
> -  if (Volume->PartitionDescs == NULL) {
> -    Status = EFI_OUT_OF_RESOURCES;
> -    goto Error_Alloc_Pds;
> -  }
> -
> -  Buffer = AllocateZeroPool (BlockSize);
> +  Buffer = AllocateZeroPool ((UINTN)BlockSize);
>    if (Buffer == NULL) {
> -    Status = EFI_OUT_OF_RESOURCES;
> -    goto Error_Alloc_Buf;
> +    return EFI_OUT_OF_RESOURCES;
>    }
> 
> -  Volume->LogicalVolDescsNo  = 0;
> -  Volume->PartitionDescsNo   = 0;
> -
> -  while (StartingLsn <= EndingLsn) {
> -    Status = DiskIo->ReadDisk (
> -      DiskIo,
> +  //
> +  // The logical partition created by Partition driver is relative to the main
> +  // VDS extent location, so we start the Main Volume Descriptor Sequence at
> +  // LBA 0.
> +  //
> +  // We don't need to check again if we have valid Volume Descriptors here
> since
> +  // Partition driver already did.
> +  //
> +  SeqStartBlock = 0;
> +  SeqEndBlock = SeqStartBlock + DivU64x32 ((UINT64)ExtentAd->ExtentLength,
> +                                           BlockSize);
> +  StopSequence = FALSE;
> +  for (; SeqStartBlock < SeqEndBlock && !StopSequence; SeqStartBlock++) {
> +    //
> +    // Read disk block
> +    //
> +    Status = BlockIo->ReadBlocks (
> +      BlockIo,
>        BlockIo->Media->MediaId,
> -      MultU64x32 (StartingLsn, BlockSize),
> +      SeqStartBlock,
>        BlockSize,
>        Buffer
>        );
>      if (EFI_ERROR (Status)) {
> -      goto Error_Read_Disk_Blk;
> +      goto Out_Free;
>      }
> 
> -    if (IS_TD (Buffer)) {
> +    DescriptorTag = Buffer;
> +
> +    switch (UDF_TAG_ID (DescriptorTag)) {
> +    case UdfPartitionDescriptor:
>        //
> -      // Found a Terminating Descriptor. Stop the sequence then.
> +      // Save Partition Descriptor
>        //
> +      CopyMem (&Volume->PartitionDesc, Buffer, sizeof (Volume-
> >PartitionDesc));
>        break;
> -    }
> 
> -    if (IS_LVD (Buffer)) {
> +    case UdfLogicalVolumeDescriptor:
>        //
> -      // Found a Logical Volume Descriptor.
> +      // Save Logical Volume Descriptor
>        //
> -      LogicalVolDesc =
> -        (UDF_LOGICAL_VOLUME_DESCRIPTOR *)
> -        AllocateZeroPool (sizeof (UDF_LOGICAL_VOLUME_DESCRIPTOR));
> -      if (LogicalVolDesc == NULL) {
> -        Status = EFI_OUT_OF_RESOURCES;
> -        goto Error_Alloc_Lvd;
> -      }
> +      CopyMem (&Volume->LogicalVolDesc, Buffer, sizeof (Volume-
> >LogicalVolDesc));
> +      break;
> 
> -      CopyMem ((VOID *)LogicalVolDesc, Buffer,
> -               sizeof (UDF_LOGICAL_VOLUME_DESCRIPTOR));
> -      Volume->LogicalVolDescs[Volume->LogicalVolDescsNo++] =
> LogicalVolDesc;
> -    } else if (IS_PD (Buffer)) {
> -      //
> -      // Found a Partition Descriptor.
> -      //
> -      PartitionDesc =
> -        (UDF_PARTITION_DESCRIPTOR *)
> -        AllocateZeroPool (sizeof (UDF_PARTITION_DESCRIPTOR));
> -      if (PartitionDesc == NULL) {
> -        Status = EFI_OUT_OF_RESOURCES;
> -        goto Error_Alloc_Pd;
> -      }
> +    case UdfTerminatingDescriptor:
> +      StopSequence = TRUE;
> +      break;
> 
> -      CopyMem ((VOID *)PartitionDesc, Buffer,
> -               sizeof (UDF_PARTITION_DESCRIPTOR));
> -      Volume->PartitionDescs[Volume->PartitionDescsNo++] = PartitionDesc;
> +    default:
> +      ;
>      }
> -
> -    StartingLsn++;
>    }
> 
>    //
> -  // When an UDF volume (revision 2.00 or higher) contains a File Entry rather
> -  // than an Extended File Entry (which is not recommended as per spec), we
> need
> -  // to make sure the size of a FE will be _at least_ 2048
> -  // (UDF_LOGICAL_SECTOR_SIZE) bytes long to keep backward compatibility.
> +  // Determine FE (File Entry) size
>    //
> -  LogicalBlockSize = LV_BLOCK_SIZE (Volume, UDF_DEFAULT_LV_NUM);
> +  LogicalBlockSize = Volume->LogicalVolDesc.LogicalBlockSize;
>    if (LogicalBlockSize >= UDF_LOGICAL_SECTOR_SIZE) {
> -    Volume->FileEntrySize = LogicalBlockSize;
> +    Volume->FileEntrySize = (UINTN)LogicalBlockSize;
>    } else {
>      Volume->FileEntrySize = UDF_LOGICAL_SECTOR_SIZE;
>    }
> 
> -  FreePool (Buffer);
> +  Status = EFI_SUCCESS;
> 
> -  return EFI_SUCCESS;
> -
> -Error_Alloc_Pd:
> -Error_Alloc_Lvd:
> -  for (Index = 0; Index < Volume->PartitionDescsNo; Index++) {
> -    FreePool ((VOID *)Volume->PartitionDescs[Index]);
> -  }
> -
> -  for (Index = 0; Index < Volume->LogicalVolDescsNo; Index++) {
> -    FreePool ((VOID *)Volume->LogicalVolDescs[Index]);
> -  }
> -
> -Error_Read_Disk_Blk:
> +Out_Free:
> +  //
> +  // Free block read buffer
> +  //
>    FreePool (Buffer);
> 
> -Error_Alloc_Buf:
> -  FreePool ((VOID *)Volume->PartitionDescs);
> -  Volume->PartitionDescs = NULL;
> -
> -Error_Alloc_Pds:
> -  FreePool ((VOID *)Volume->LogicalVolDescs);
> -  Volume->LogicalVolDescs = NULL;
> -
>    return Status;
>  }
> 
> @@ -262,48 +216,53 @@ GetPdFromLongAd (
>    )
>  {
>    UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;
> -  UINTN                          Index;
> -  UDF_PARTITION_DESCRIPTOR       *PartitionDesc;
>    UINT16                         PartitionNum;
> 
> -  LogicalVolDesc = Volume->LogicalVolDescs[UDF_DEFAULT_LV_NUM];
> +  LogicalVolDesc = &Volume->LogicalVolDesc;
> 
> -  switch (LV_UDF_REVISION (LogicalVolDesc)) {
> +  switch (UDF_LVD_REVISION (LogicalVolDesc)) {
>    case 0x0102:
> +  case 0x0150:
> +  case 0x0200:
> +  case 0x0201:
> +  case 0x0250:
> +  case 0x0260:
>      //
> -    // As per UDF 1.02 specification:
> +    // UDF 1.02 specification:
>      //
>      // There shall be exactly one prevailing Logical Volume Descriptor recorded
>      // per Volume Set. The Partition Maps field shall contain only Type 1
>      // Partition Maps.
>      //
> -    PartitionNum = *(UINT16 *)((UINTN)&LogicalVolDesc->PartitionMaps[4]);
> -    break;
> -  case 0x0150:
> +    // UDF 1.50 through 2.60 specs say:
>      //
> -    // Ensure Type 1 Partition map. Other types aren't supported in this
> -    // implementation.
> +    // For the purpose of interchange partition maps shall be limited to
> +    // Partition Map type 1, except type 2 maps as described in the document.
> +    //
> +    // NOTE: Only one Type 1 (Physical) Partition is supported. It has been
> +    // checked already in Partition driver for existence of a single Type 1
> +    // Partition map, so we don't have to double check here.
> +    //
> +    // Partition reference number can also be retrieved from
> +    // LongAd->ExtentLocation.PartitionReferenceNumber, however the spec
> says
> +    // it may be 0, so let's not rely on it.
>      //
> -    if (LogicalVolDesc->PartitionMaps[0] != 1 ||
> -        LogicalVolDesc->PartitionMaps[1] != 6) {
> -      return NULL;
> -    }
>      PartitionNum = *(UINT16 *)((UINTN)&LogicalVolDesc->PartitionMaps[4]);
>      break;
> -  case 0x0260:
> +
> +  default:
>      //
> -    // Fall through.
> +    // Unsupported UDF revision
>      //
> -  default:
> -    PartitionNum = LongAd->ExtentLocation.PartitionReferenceNumber;
> -    break;
> +    return NULL;
>    }
> 
> -  for (Index = 0; Index < Volume->PartitionDescsNo; Index++) {
> -    PartitionDesc = Volume->PartitionDescs[Index];
> -    if (PartitionDesc->PartitionNumber == PartitionNum) {
> -      return PartitionDesc;
> -    }
> +  //
> +  // Check if partition number matches Partition Descriptor found in Main
> Volume
> +  // Descriptor Sequence.
> +  //
> +  if (Volume->PartitionDesc.PartitionNumber == PartitionNum) {
> +    return &Volume->PartitionDesc;
>    }
> 
>    return NULL;
> @@ -329,13 +288,15 @@ GetLongAdLsn (
>    PartitionDesc = GetPdFromLongAd (Volume, LongAd);
>    ASSERT (PartitionDesc != NULL);
> 
> -  return (UINT64)PartitionDesc->PartitionStartingLocation +
> -                 LongAd->ExtentLocation.LogicalBlockNumber;
> +  return (UINT64)PartitionDesc->PartitionStartingLocation -
> +    Volume->MainVdsStartLocation +
> +    LongAd->ExtentLocation.LogicalBlockNumber;
>  }
> 
>  /**
>    Return logical sector number of a given Short Allocation Descriptor.
> 
> +  @param[in]  Volume              Volume pointer.
>    @param[in]  PartitionDesc       Partition Descriptor pointer.
>    @param[in]  ShortAd             Short Allocation Descriptor pointer.
> 
> @@ -344,14 +305,13 @@ GetLongAdLsn (
>  **/
>  UINT64
>  GetShortAdLsn (
> +  IN UDF_VOLUME_INFO                  *Volume,
>    IN UDF_PARTITION_DESCRIPTOR         *PartitionDesc,
>    IN UDF_SHORT_ALLOCATION_DESCRIPTOR  *ShortAd
>    )
>  {
> -  ASSERT (PartitionDesc != NULL);
> -
> -  return (UINT64)PartitionDesc->PartitionStartingLocation +
> -    ShortAd->ExtentPosition;
> +  return (UINT64)PartitionDesc->PartitionStartingLocation -
> +    Volume->MainVdsStartLocation + ShortAd->ExtentPosition;
>  }
> 
>  /**
> @@ -363,8 +323,6 @@ GetShortAdLsn (
>    @param[in]  BlockIo             BlockIo interface.
>    @param[in]  DiskIo              DiskIo interface.
>    @param[in]  Volume              Volume information pointer.
> -  @param[in]  LogicalVolDescNum   Index of Logical Volume Descriptor
> -  @param[out] FileSetDesc         File Set Descriptor pointer.
> 
>    @retval EFI_SUCCESS             File Set Descriptor pointer found.
>    @retval EFI_VOLUME_CORRUPTED    The file system structures are
> corrupted.
> @@ -375,36 +333,42 @@ EFI_STATUS
>  FindFileSetDescriptor (
>    IN   EFI_BLOCK_IO_PROTOCOL    *BlockIo,
>    IN   EFI_DISK_IO_PROTOCOL     *DiskIo,
> -  IN   UDF_VOLUME_INFO          *Volume,
> -  IN   UINTN                    LogicalVolDescNum,
> -  OUT  UDF_FILE_SET_DESCRIPTOR  *FileSetDesc
> +  IN   UDF_VOLUME_INFO          *Volume
>    )
>  {
>    EFI_STATUS                     Status;
>    UINT64                         Lsn;
>    UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;
> +  UDF_DESCRIPTOR_TAG             *DescriptorTag;
> 
> -  LogicalVolDesc = Volume->LogicalVolDescs[LogicalVolDescNum];
> +  LogicalVolDesc = &Volume->LogicalVolDesc;
>    Lsn = GetLongAdLsn (Volume, &LogicalVolDesc->LogicalVolumeContentsUse);
> 
>    //
> -  // Read extent (Long Ad).
> +  // As per UDF 2.60 specification:
> +  //
> +  // There shall be exactly one File Set Descriptor recorded per Logical
> +  // Volume.
> +  //
> +  // Read disk block
>    //
>    Status = DiskIo->ReadDisk (
>      DiskIo,
>      BlockIo->Media->MediaId,
>      MultU64x32 (Lsn, LogicalVolDesc->LogicalBlockSize),
> -    sizeof (UDF_FILE_SET_DESCRIPTOR),
> -    (VOID *)FileSetDesc
> +    sizeof (Volume->FileSetDesc),
> +    &Volume->FileSetDesc
>      );
>    if (EFI_ERROR (Status)) {
>      return Status;
>    }
> 
> +  DescriptorTag = &Volume->FileSetDesc.DescriptorTag;
> +
>    //
> -  // Check if the read extent contains a valid FSD's tag identifier.
> +  // Check if read block is a File Set Descriptor
>    //
> -  if (!IS_FSD (FileSetDesc)) {
> +  if (UDF_TAG_ID (DescriptorTag) != UdfFileSetDescriptor) {
>      return EFI_VOLUME_CORRUPTED;
>    }
> 
> @@ -412,82 +376,6 @@ FindFileSetDescriptor (
>  }
> 
>  /**
> -  Get all File Set Descriptors for each Logical Volume Descriptor.
> -
> -  @param[in]      BlockIo         BlockIo interface.
> -  @param[in]      DiskIo          DiskIo interface.
> -  @param[in, out] Volume          Volume information pointer.
> -
> -  @retval EFI_SUCCESS             File Set Descriptors were got.
> -  @retval EFI_OUT_OF_RESOURCES    File Set Descriptors were not got due to
> lack
> -                                  of resources.
> -  @retval other                   Error occured when finding File Set
> -                                  Descriptor in Logical Volume Descriptor.
> -
> -**/
> -EFI_STATUS
> -GetFileSetDescriptors (
> -  IN      EFI_BLOCK_IO_PROTOCOL  *BlockIo,
> -  IN      EFI_DISK_IO_PROTOCOL   *DiskIo,
> -  IN OUT  UDF_VOLUME_INFO        *Volume
> -  )
> -{
> -  EFI_STATUS               Status;
> -  UINTN                    Index;
> -  UDF_FILE_SET_DESCRIPTOR  *FileSetDesc;
> -  UINTN                    Count;
> -
> -  Volume->FileSetDescs =
> -    (UDF_FILE_SET_DESCRIPTOR **)AllocateZeroPool (
> -      Volume->LogicalVolDescsNo * sizeof (UDF_FILE_SET_DESCRIPTOR));
> -  if (Volume->FileSetDescs == NULL) {
> -    return EFI_OUT_OF_RESOURCES;
> -  }
> -
> -  for (Index = 0; Index < Volume->LogicalVolDescsNo; Index++) {
> -    FileSetDesc = AllocateZeroPool (sizeof (UDF_FILE_SET_DESCRIPTOR));
> -    if (FileSetDesc == NULL) {
> -      Status = EFI_OUT_OF_RESOURCES;
> -      goto Error_Alloc_Fsd;
> -    }
> -
> -    //
> -    // Find a FSD for this LVD.
> -    //
> -    Status = FindFileSetDescriptor (
> -      BlockIo,
> -      DiskIo,
> -      Volume,
> -      Index,
> -      FileSetDesc
> -      );
> -    if (EFI_ERROR (Status)) {
> -      goto Error_Find_Fsd;
> -    }
> -
> -    //
> -    // Got one. Save it.
> -    //
> -    Volume->FileSetDescs[Index] = FileSetDesc;
> -  }
> -
> -  Volume->FileSetDescsNo = Volume->LogicalVolDescsNo;
> -  return EFI_SUCCESS;
> -
> -Error_Find_Fsd:
> -  Count = Index + 1;
> -  for (Index = 0; Index < Count; Index++) {
> -    FreePool ((VOID *)Volume->FileSetDescs[Index]);
> -  }
> -
> -  FreePool ((VOID *)Volume->FileSetDescs);
> -  Volume->FileSetDescs = NULL;
> -
> -Error_Alloc_Fsd:
> -  return Status;
> -}
> -
> -/**
>    Read Volume and File Structure on an UDF file system.
> 
>    @param[in]   BlockIo            BlockIo interface.
> @@ -507,9 +395,10 @@ ReadVolumeFileStructure (
>  {
>    EFI_STATUS                            Status;
>    UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  AnchorPoint;
> +  UDF_EXTENT_AD                         *ExtentAd;
> 
>    //
> -  // Find an AVDP.
> +  // Find Anchor Volume Descriptor Pointer
>    //
>    Status = FindAnchorVolumeDescriptorPointer (
>      BlockIo,
> @@ -521,7 +410,14 @@ ReadVolumeFileStructure (
>    }
> 
>    //
> -  // AVDP has been found. Start MVDS.
> +  // Save Main VDS start block number
> +  //
> +  ExtentAd = &AnchorPoint.MainVolumeDescriptorSequenceExtent;
> +
> +  Volume->MainVdsStartLocation = (UINT64)ExtentAd->ExtentLocation;
> +
> +  //
> +  // Start Main Volume Descriptor Sequence.
>    //
>    Status = StartMainVolumeDescriptorSequence (
>      BlockIo,
> @@ -620,16 +516,19 @@ GetFileEntryData (
>    OUT  UINT64  *Length
>    )
>  {
> +  UDF_DESCRIPTOR_TAG       *DescriptorTag;
>    UDF_EXTENDED_FILE_ENTRY  *ExtendedFileEntry;
>    UDF_FILE_ENTRY           *FileEntry;
> 
> -  if (IS_EFE (FileEntryData)) {
> +  DescriptorTag = FileEntryData;
> +
> +  if (UDF_TAG_ID (DescriptorTag) == UdfExtendedFileEntry) {
>      ExtendedFileEntry = (UDF_EXTENDED_FILE_ENTRY *)FileEntryData;
> 
>      *Length  = ExtendedFileEntry->InformationLength;
>      *Data    = (VOID *)((UINT8 *)ExtendedFileEntry->Data +
>                          ExtendedFileEntry->LengthOfExtendedAttributes);
> -  } else if (IS_FE (FileEntryData)) {
> +  } else if (UDF_TAG_ID (DescriptorTag) == UdfFileEntry) {
>      FileEntry = (UDF_FILE_ENTRY *)FileEntryData;
> 
>      *Length  = FileEntry->InformationLength;
> @@ -654,16 +553,19 @@ GetAdsInformation (
>    OUT  UINT64  *Length
>    )
>  {
> +  UDF_DESCRIPTOR_TAG       *DescriptorTag;
>    UDF_EXTENDED_FILE_ENTRY  *ExtendedFileEntry;
>    UDF_FILE_ENTRY           *FileEntry;
> 
> -  if (IS_EFE (FileEntryData)) {
> +  DescriptorTag = FileEntryData;
> +
> +  if (UDF_TAG_ID (DescriptorTag) == UdfExtendedFileEntry) {
>      ExtendedFileEntry = (UDF_EXTENDED_FILE_ENTRY *)FileEntryData;
> 
>      *Length = ExtendedFileEntry->LengthOfAllocationDescriptors;
>      *AdsData = (VOID *)((UINT8 *)ExtendedFileEntry->Data +
>                          ExtendedFileEntry->LengthOfExtendedAttributes);
> -  } else if (IS_FE (FileEntryData)) {
> +  } else if (UDF_TAG_ID (DescriptorTag) == UdfFileEntry) {
>      FileEntry = (UDF_FILE_ENTRY *)FileEntryData;
> 
>      *Length = FileEntry->LengthOfAllocationDescriptors;
> @@ -850,6 +752,7 @@ GetAllocationDescriptorLsn (
>      return GetLongAdLsn (Volume, (UDF_LONG_ALLOCATION_DESCRIPTOR
> *)Ad);
>    } else if (RecordingFlags == ShortAdsSequence) {
>      return GetShortAdLsn (
> +      Volume,
>        GetPdFromLongAd (Volume, ParentIcb),
>        (UDF_SHORT_ALLOCATION_DESCRIPTOR *)Ad
>        );
> @@ -897,6 +800,7 @@ GetAedAdsOffset (
>    VOID                              *Data;
>    UINT32                            LogicalBlockSize;
>    UDF_ALLOCATION_EXTENT_DESCRIPTOR  *AllocExtDesc;
> +  UDF_DESCRIPTOR_TAG                *DescriptorTag;
> 
>    ExtentLength  = GET_EXTENT_LENGTH (RecordingFlags, Ad);
>    Lsn           = GetAllocationDescriptorLsn (RecordingFlags,
> @@ -909,7 +813,7 @@ GetAedAdsOffset (
>      return EFI_OUT_OF_RESOURCES;
>    }
> 
> -  LogicalBlockSize = LV_BLOCK_SIZE (Volume, UDF_DEFAULT_LV_NUM);
> +  LogicalBlockSize = Volume->LogicalVolDesc.LogicalBlockSize;
> 
>    //
>    // Read extent.
> @@ -925,11 +829,14 @@ GetAedAdsOffset (
>      goto Exit;
>    }
> 
> +  AllocExtDesc = (UDF_ALLOCATION_EXTENT_DESCRIPTOR *)Data;
> +
> +  DescriptorTag = &AllocExtDesc->DescriptorTag;
> +
>    //
>    // Check if read extent contains a valid tag identifier for AED.
>    //
> -  AllocExtDesc = (UDF_ALLOCATION_EXTENT_DESCRIPTOR *)Data;
> -  if (!IS_AED (AllocExtDesc)) {
> +  if (UDF_TAG_ID (DescriptorTag) != UdfAllocationExtentDescriptor) {
>      Status = EFI_VOLUME_CORRUPTED;
>      goto Exit;
>    }
> @@ -1102,7 +1009,7 @@ ReadFile (
>    UINT32                  ExtentLength;
>    UDF_FE_RECORDING_FLAGS  RecordingFlags;
> 
> -  LogicalBlockSize  = LV_BLOCK_SIZE (Volume, UDF_DEFAULT_LV_NUM);
> +  LogicalBlockSize  = Volume->LogicalVolDesc.LogicalBlockSize;
>    DoFreeAed         = FALSE;
> 
>    //
> @@ -1444,7 +1351,7 @@ InternalFindFile (
>    //
>    // Check if parent file is really directory.
>    //
> -  if (!IS_FE_DIRECTORY (Parent->FileEntry)) {
> +  if (FE_ICB_FILE_TYPE (Parent->FileEntry) != UdfFileEntryDirectory) {
>      return EFI_NOT_FOUND;
>    }
> 
> @@ -1489,7 +1396,7 @@ InternalFindFile (
>        break;
>      }
> 
> -    if (IS_FID_PARENT_FILE (FileIdentifierDesc)) {
> +    if (FileIdentifierDesc->FileCharacteristics & PARENT_FILE) {
>        //
>        // This FID contains the location (FE/EFE) of the parent directory of this
>        // directory (Parent), and if FileName is either ".." or "\\", then it's
> @@ -1592,6 +1499,9 @@ ReadUdfVolumeInformation (
>  {
>    EFI_STATUS Status;
> 
> +  //
> +  // Read all necessary UDF volume information and keep it private to the
> driver
> +  //
>    Status = ReadVolumeFileStructure (
>      BlockIo,
>      DiskIo,
> @@ -1601,13 +1511,12 @@ ReadUdfVolumeInformation (
>      return Status;
>    }
> 
> -  Status = GetFileSetDescriptors (
> -    BlockIo,
> -    DiskIo,
> -    Volume
> -    );
> +  //
> +  // Find File Set Descriptor
> +  //
> +  Status = FindFileSetDescriptor (BlockIo, DiskIo, Volume);
>    if (EFI_ERROR (Status)) {
> -    CleanupVolumeInformation (Volume);
> +    return Status;
>    }
> 
>    return Status;
> @@ -1644,7 +1553,7 @@ FindRootDirectory (
>      BlockIo,
>      DiskIo,
>      Volume,
> -    &Volume->FileSetDescs[0]->RootDirectoryIcb,
> +    &Volume->FileSetDesc.RootDirectoryIcb,
>      &File->FileEntry
>      );
>    if (EFI_ERROR (Status)) {
> @@ -1661,7 +1570,7 @@ FindRootDirectory (
>      L"\\",
>      NULL,
>      &Parent,
> -    &Volume->FileSetDescs[0]->RootDirectoryIcb,
> +    &Volume->FileSetDesc.RootDirectoryIcb,
>      File
>      );
>    if (EFI_ERROR (Status)) {
> @@ -1697,12 +1606,13 @@ FindFileEntry (
>    OUT  VOID                            **FileEntry
>    )
>  {
> -  EFI_STATUS  Status;
> -  UINT64      Lsn;
> -  UINT32      LogicalBlockSize;
> +  EFI_STATUS          Status;
> +  UINT64              Lsn;
> +  UINT32              LogicalBlockSize;
> +  UDF_DESCRIPTOR_TAG  *DescriptorTag;
> 
>    Lsn               = GetLongAdLsn (Volume, Icb);
> -  LogicalBlockSize  = LV_BLOCK_SIZE (Volume, UDF_DEFAULT_LV_NUM);
> +  LogicalBlockSize  = Volume->LogicalVolDesc.LogicalBlockSize;
> 
>    *FileEntry = AllocateZeroPool (Volume->FileEntrySize);
>    if (*FileEntry == NULL) {
> @@ -1723,11 +1633,14 @@ FindFileEntry (
>      goto Error_Read_Disk_Blk;
>    }
> 
> +  DescriptorTag = *FileEntry;
> +
>    //
>    // Check if the read extent contains a valid Tag Identifier for the expected
>    // FE/EFE.
>    //
> -  if (!IS_FE (*FileEntry) && !IS_EFE (*FileEntry)) {
> +  if (UDF_TAG_ID (DescriptorTag) != UdfFileEntry &&
> +      UDF_TAG_ID (DescriptorTag) != UdfExtendedFileEntry) {
>      Status = EFI_VOLUME_CORRUPTED;
>      goto Error_Invalid_Fe;
>    }
> @@ -1837,7 +1750,7 @@ FindFile (
>      // If the found file is a symlink, then find its respective FE/EFE and
>      // FID descriptors.
>      //
> -    if (IS_FE_SYMLINK (File->FileEntry)) {
> +    if (FE_ICB_FILE_TYPE (File->FileEntry) == UdfFileEntrySymlink) {
>        FreePool ((VOID *)File->FileIdentifierDesc);
> 
>        FileEntry = File->FileEntry;
> @@ -1951,7 +1864,7 @@ ReadDirectoryEntry (
>      // Update FidOffset to point to next FID.
>      //
>      ReadDirInfo->FidOffset += GetFidDescriptorLength (FileIdentifierDesc);
> -  } while (IS_FID_DELETED_FILE (FileIdentifierDesc));
> +  } while (FileIdentifierDesc->FileCharacteristics & DELETED_FILE);
> 
>    DuplicateFid (FileIdentifierDesc, FoundFid);
> 
> @@ -2197,43 +2110,6 @@ Error_Find_File:
>  }
> 
>  /**
> -  Clean up in-memory UDF volume information.
> -
> -  @param[in] Volume Volume information pointer.
> -
> -**/
> -VOID
> -CleanupVolumeInformation (
> -  IN UDF_VOLUME_INFO *Volume
> -  )
> -{
> -  UINTN Index;
> -
> -  if (Volume->LogicalVolDescs != NULL) {
> -    for (Index = 0; Index < Volume->LogicalVolDescsNo; Index++) {
> -      FreePool ((VOID *)Volume->LogicalVolDescs[Index]);
> -    }
> -    FreePool ((VOID *)Volume->LogicalVolDescs);
> -  }
> -
> -  if (Volume->PartitionDescs != NULL) {
> -    for (Index = 0; Index < Volume->PartitionDescsNo; Index++) {
> -      FreePool ((VOID *)Volume->PartitionDescs[Index]);
> -    }
> -    FreePool ((VOID *)Volume->PartitionDescs);
> -  }
> -
> -  if (Volume->FileSetDescs != NULL) {
> -    for (Index = 0; Index < Volume->FileSetDescsNo; Index++) {
> -      FreePool ((VOID *)Volume->FileSetDescs[Index]);
> -    }
> -    FreePool ((VOID *)Volume->FileSetDescs);
> -  }
> -
> -  ZeroMem ((VOID *)Volume, sizeof (UDF_VOLUME_INFO));
> -}
> -
> -/**
>    Clean up in-memory UDF file information.
> 
>    @param[in] File File information pointer.
> @@ -2333,6 +2209,7 @@ SetFileInfo (
>    EFI_FILE_INFO            *FileInfo;
>    UDF_FILE_ENTRY           *FileEntry;
>    UDF_EXTENDED_FILE_ENTRY  *ExtendedFileEntry;
> +  UDF_DESCRIPTOR_TAG       *DescriptorTag;
> 
>    //
>    // Calculate the needed size for the EFI_FILE_INFO structure.
> @@ -2367,7 +2244,9 @@ SetFileInfo (
>      FileInfo->Attribute |= EFI_FILE_HIDDEN;
>    }
> 
> -  if (IS_FE (File->FileEntry)) {
> +  DescriptorTag = File->FileEntry;
> +
> +  if (UDF_TAG_ID (DescriptorTag) == UdfFileEntry) {
>      FileEntry = (UDF_FILE_ENTRY *)File->FileEntry;
> 
>      //
> @@ -2403,7 +2282,7 @@ SetFileInfo (
>                                     FileEntry->AccessTime.Second;
>      FileInfo->LastAccessTime.Nanosecond  =
>                                     FileEntry->AccessTime.HundredsOfMicroseconds;
> -  } else if (IS_EFE (File->FileEntry)) {
> +  } else if (UDF_TAG_ID (DescriptorTag) == UdfExtendedFileEntry) {
>      ExtendedFileEntry = (UDF_EXTENDED_FILE_ENTRY *)File->FileEntry;
> 
>      //
> @@ -2487,91 +2366,103 @@ GetVolumeSize (
>    OUT  UINT64                 *FreeSpaceSize
>    )
>  {
> -  UDF_EXTENT_AD                 ExtentAd;
> -  UINT32                        LogicalBlockSize;
> -  UINT64                        Lsn;
> -  EFI_STATUS                    Status;
> -  UDF_LOGICAL_VOLUME_INTEGRITY  *LogicalVolInt;
> -  UINTN                         Index;
> -  UINTN                         Length;
> -  UINT32                        LsnsNo;
> -
> -  *VolumeSize     = 0;
> -  *FreeSpaceSize  = 0;
> -
> -  for (Index = 0; Index < Volume->LogicalVolDescsNo; Index++) {
> -    CopyMem ((VOID *)&ExtentAd,
> -             (VOID *)&Volume->LogicalVolDescs[Index]->IntegritySequenceExtent,
> -             sizeof (UDF_EXTENT_AD));
> -    if (ExtentAd.ExtentLength == 0) {
> -      continue;
> -    }
> +  EFI_STATUS                     Status;
> +  UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;
> +  UDF_EXTENT_AD                  *ExtentAd;
> +  UINT64                         Lsn;
> +  UINT32                         LogicalBlockSize;
> +  UDF_LOGICAL_VOLUME_INTEGRITY   *LogicalVolInt;
> +  UDF_DESCRIPTOR_TAG             *DescriptorTag;
> +  UINTN                          Index;
> +  UINTN                          Length;
> +  UINT32                         LsnsNo;
> 
> -    LogicalBlockSize = LV_BLOCK_SIZE (Volume, Index);
> +  LogicalVolDesc = &Volume->LogicalVolDesc;
> 
> -  Read_Next_Sequence:
> -    LogicalVolInt = (UDF_LOGICAL_VOLUME_INTEGRITY *)
> -      AllocatePool (ExtentAd.ExtentLength);
> -    if (LogicalVolInt == NULL) {
> -      return EFI_OUT_OF_RESOURCES;
> -    }
> +  ExtentAd = &LogicalVolDesc->IntegritySequenceExtent;
> +
> +  if (ExtentAd->ExtentLength == 0) {
> +    return EFI_VOLUME_CORRUPTED;
> +  }
> 
> -    Lsn = (UINT64)ExtentAd.ExtentLocation;
> +  LogicalVolInt = AllocatePool (ExtentAd->ExtentLength);
> +  if (LogicalVolInt == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> 
> -    Status = DiskIo->ReadDisk (
> -      DiskIo,
> -      BlockIo->Media->MediaId,
> -      MultU64x32 (Lsn, LogicalBlockSize),
> -      ExtentAd.ExtentLength,
> -      (VOID *)LogicalVolInt
> -      );
> -    if (EFI_ERROR (Status)) {
> -      FreePool ((VOID *)LogicalVolInt);
> -      return Status;
> -    }
> +  //
> +  // Get location of Logical Volume Integrity Descriptor
> +  //
> +  Lsn = (UINT64)ExtentAd->ExtentLocation - Volume->MainVdsStartLocation;
> 
> -    if (!IS_LVID (LogicalVolInt)) {
> -      FreePool ((VOID *)LogicalVolInt);
> -      return EFI_VOLUME_CORRUPTED;
> -    }
> +  LogicalBlockSize = LogicalVolDesc->LogicalBlockSize;
> 
> -    Length = LogicalVolInt->NumberOfPartitions;
> -    for (Index = 0; Index < Length; Index += sizeof (UINT32)) {
> -      LsnsNo = *(UINT32 *)((UINT8 *)LogicalVolInt->Data + Index);
> -      if (LsnsNo == 0xFFFFFFFFUL) {
> -        //
> -        // Size not specified.
> -        //
> -        continue;
> -      }
> +  //
> +  // Read disk block
> +  //
> +  Status = DiskIo->ReadDisk (
> +    DiskIo,
> +    BlockIo->Media->MediaId,
> +    MultU64x32 (Lsn, LogicalBlockSize),
> +    ExtentAd->ExtentLength,
> +    LogicalVolInt
> +    );
> +  if (EFI_ERROR (Status)) {
> +    goto Out_Free;
> +  }
> 
> -      *FreeSpaceSize += MultU64x32 ((UINT64)LsnsNo, LogicalBlockSize);
> -    }
> +  DescriptorTag = &LogicalVolInt->DescriptorTag;
> 
> -    Length = (LogicalVolInt->NumberOfPartitions * sizeof (UINT32)) << 1;
> -    for (; Index < Length; Index += sizeof (UINT32)) {
> -      LsnsNo = *(UINT32 *)((UINT8 *)LogicalVolInt->Data + Index);
> -      if (LsnsNo == 0xFFFFFFFFUL) {
> -        //
> -        // Size not specified.
> -        //
> -        continue;
> -      }
> +  //
> +  // Check if read block is a Logical Volume Integrity Descriptor
> +  //
> +  if (UDF_TAG_ID (DescriptorTag) != UdfLogicalVolumeIntegrityDescriptor) {
> +    Status = EFI_VOLUME_CORRUPTED;
> +    goto Out_Free;
> +  }
> 
> -      *VolumeSize += MultU64x32 ((UINT64)LsnsNo, LogicalBlockSize);
> -    }
> +  *VolumeSize = 0;
> +  *FreeSpaceSize = 0;
> 
> -    CopyMem ((VOID *)&ExtentAd,(VOID *)&LogicalVolInt->NextIntegrityExtent,
> -             sizeof (UDF_EXTENT_AD));
> -    if (ExtentAd.ExtentLength > 0) {
> -      FreePool ((VOID *)LogicalVolInt);
> -      goto Read_Next_Sequence;
> +  Length = LogicalVolInt->NumberOfPartitions;
> +  for (Index = 0; Index < Length; Index += sizeof (UINT32)) {
> +    LsnsNo = *(UINT32 *)((UINT8 *)LogicalVolInt->Data + Index);
> +    //
> +    // Check if size is not specified
> +    //
> +    if (LsnsNo == 0xFFFFFFFFUL) {
> +      continue;
>      }
> +    //
> +    // Accumulate free space size
> +    //
> +    *FreeSpaceSize += MultU64x32 ((UINT64)LsnsNo, LogicalBlockSize);
> +  }
> 
> -    FreePool ((VOID *)LogicalVolInt);
> +  Length = LogicalVolInt->NumberOfPartitions * sizeof (UINT32) * 2;
> +  for (; Index < Length; Index += sizeof (UINT32)) {
> +    LsnsNo = *(UINT32 *)((UINT8 *)LogicalVolInt->Data + Index);
> +    //
> +    // Check if size is not specified
> +    //
> +    if (LsnsNo == 0xFFFFFFFFUL) {
> +      continue;
> +    }
> +    //
> +    // Accumulate used volume space
> +    //
> +    *VolumeSize += MultU64x32 ((UINT64)LsnsNo, LogicalBlockSize);
>    }
> 
> -  return EFI_SUCCESS;
> +  Status = EFI_SUCCESS;
> +
> +Out_Free:
> +  //
> +  // Free Logical Volume Integrity Descriptor
> +  //
> +  FreePool (LogicalVolInt);
> +
> +  return Status;
>  }
> 
>  /**
> diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/Udf.c
> b/MdeModulePkg/Universal/Disk/UdfDxe/Udf.c
> index 49dc7077b7..d4163b89ca 100644
> --- a/MdeModulePkg/Universal/Disk/UdfDxe/Udf.c
> +++ b/MdeModulePkg/Universal/Disk/UdfDxe/Udf.c
> @@ -276,13 +276,6 @@ UdfDriverBindingStop (
>        NULL
>        );
> 
> -    //
> -    // Check if there's any open file. If so, clean them up.
> -    //
> -    if (PrivFsData->OpenFiles > 0) {
> -      CleanupVolumeInformation (&PrivFsData->Volume);
> -    }
> -
>      FreePool ((VOID *)PrivFsData);
>    }
> 
> diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/Udf.h
> b/MdeModulePkg/Universal/Disk/UdfDxe/Udf.h
> index 44c843fd4d..ef2a3359ce 100644
> --- a/MdeModulePkg/Universal/Disk/UdfDxe/Udf.h
> +++ b/MdeModulePkg/Universal/Disk/UdfDxe/Udf.h
> @@ -49,61 +49,34 @@
>      { 0x89, 0x56, 0x73, 0xCD, 0xA3, 0x26, 0xCD, 0x0A }  \
>    }
> 
> -#define UDF_DEFAULT_LV_NUM 0
> -
> -#define IS_PVD(_Pointer) \
> -  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 1))
> -#define IS_PD(_Pointer) \
> -  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 5))
> -#define IS_LVD(_Pointer) \
> -  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 6))
> -#define IS_TD(_Pointer) \
> -  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 8))
> -#define IS_FSD(_Pointer) \
> -  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 256))
> -#define IS_FE(_Pointer) \
> -  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 261))
> -#define IS_EFE(_Pointer) \
> -  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 266))
> -#define IS_FID(_Pointer) \
> -  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 257))
> -#define IS_AED(_Pointer) \
> -  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 258))
> -#define IS_LVID(_Pointer) \
> -  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 9))
> -
> -#define _GET_FILETYPE(_Pointer) \
> -  (IS_FE (_Pointer) ? \
> -   (((UDF_FILE_ENTRY *)(_Pointer))->IcbTag.FileType) \
> -   : \
> -   (((UDF_EXTENDED_FILE_ENTRY *)(_Pointer))->IcbTag.FileType))
> -
> -#define IS_FE_DIRECTORY(_Pointer) \
> -  ((BOOLEAN)(_GET_FILETYPE (_Pointer) == 4))
> -#define IS_FE_STANDARD_FILE(_Pointer) \
> -  ((BOOLEAN)(_GET_FILETYPE (_Pointer) == 5))
> -#define IS_FE_SYMLINK(_Pointer) \
> -  ((BOOLEAN)(_GET_FILETYPE (_Pointer) == 12))
> +#define FE_ICB_FILE_TYPE(_Ptr) \
> +  (UDF_FILE_ENTRY_TYPE)( \
> +  (UDF_TAG_ID ((UDF_DESCRIPTOR_TAG *)(_Ptr)) == UdfFileEntry ? \
> +   ((UDF_FILE_ENTRY *)(_Ptr))->IcbTag.FileType : \
> +   ((UDF_EXTENDED_FILE_ENTRY *)(_Ptr))->IcbTag.FileType))
> +
> +typedef enum {
> +  UdfFileEntryDirectory = 4,
> +  UdfFileEntryStandardFile = 5,
> +  UdfFileEntrySymlink = 12,
> +} UDF_FILE_ENTRY_TYPE;
> 
>  #define HIDDEN_FILE     (1 << 0)
>  #define DIRECTORY_FILE  (1 << 1)
>  #define DELETED_FILE    (1 << 2)
>  #define PARENT_FILE     (1 << 3)
> 
> -#define _GET_FILE_CHARS(_Pointer) \
> -  (((UDF_FILE_IDENTIFIER_DESCRIPTOR *)(_Pointer))->FileCharacteristics)
> -
> -#define IS_FID_HIDDEN_FILE(_Pointer) \
> -  ((BOOLEAN)(_GET_FILE_CHARS (_Pointer) & HIDDEN_FILE))
> -#define IS_FID_DIRECTORY_FILE(_Pointer) \
> -  ((BOOLEAN)(_GET_FILE_CHARS (_Pointer) & DIRECTORY_FILE))
> -#define IS_FID_DELETED_FILE(_Pointer) \
> -  ((BOOLEAN)(_GET_FILE_CHARS (_Pointer) & DELETED_FILE))
> -#define IS_FID_PARENT_FILE(_Pointer) \
> -  ((BOOLEAN)(_GET_FILE_CHARS (_Pointer) & PARENT_FILE))
> -#define IS_FID_NORMAL_FILE(_Pointer) \
> -  ((BOOLEAN)(!IS_FID_DIRECTORY_FILE (_Pointer) && \
> -         !IS_FID_PARENT_FILE (_Pointer)))
> +#define IS_FID_HIDDEN_FILE(_Fid) \
> +  (BOOLEAN)((_Fid)->FileCharacteristics & HIDDEN_FILE)
> +#define IS_FID_DIRECTORY_FILE(_Fid) \
> +  (BOOLEAN)((_Fid)->FileCharacteristics & DIRECTORY_FILE)
> +#define IS_FID_DELETED_FILE(_Fid) \
> +  (BOOLEAN)((_Fid)->FileCharacteristics & DELETED_FILE)
> +#define IS_FID_PARENT_FILE(_Fid) \
> +  (BOOLEAN)((_Fid)->FileCharacteristics & PARENT_FILE)
> +#define IS_FID_NORMAL_FILE(_Fid) \
> +  (BOOLEAN)(!IS_FID_DIRECTORY_FILE (_Fid) && \
> +            !IS_FID_PARENT_FILE (_Fid))
> 
>  typedef enum {
>    ShortAdsSequence,
> @@ -152,14 +125,8 @@ typedef enum {
>  #define IS_VALID_COMPRESSION_ID(_CompId) \
>    ((BOOLEAN)((_CompId) == 8 || (_CompId) == 16))
> 
> -#define LV_BLOCK_SIZE(_Vol, _LvNum) \
> -  (_Vol)->LogicalVolDescs[(_LvNum)]->LogicalBlockSize
> -
>  #define UDF_STANDARD_IDENTIFIER_LENGTH   5
> 
> -#define LV_UDF_REVISION(_Lv) \
> -  *(UINT16 *)(UINTN)(_Lv)->DomainIdentifier.IdentifierSuffix
> -
>  #pragma pack(1)
> 
>  typedef struct {
> @@ -186,17 +153,6 @@ typedef struct {
>  #pragma pack(1)
> 
>  typedef struct {
> -  UINT8           CharacterSetType;
> -  UINT8           CharacterSetInfo[63];
> -} UDF_CHAR_SPEC;
> -
> -typedef struct {
> -  UINT8           Flags;
> -  UINT8           Identifier[23];
> -  UINT8           IdentifierSuffix[8];
> -} UDF_ENTITY_ID;
> -
> -typedef struct {
>    UINT16          TypeAndTimezone;
>    INT16           Year;
>    UINT8           Month;
> @@ -210,17 +166,6 @@ typedef struct {
>  } UDF_TIMESTAMP;
> 
>  typedef struct {
> -  UINT32        LogicalBlockNumber;
> -  UINT16        PartitionReferenceNumber;
> -} UDF_LB_ADDR;
> -
> -typedef struct {
> -  UINT32                           ExtentLength;
> -  UDF_LB_ADDR                      ExtentLocation;
> -  UINT8                            ImplementationUse[6];
> -} UDF_LONG_ALLOCATION_DESCRIPTOR;
> -
> -typedef struct {
>    UDF_DESCRIPTOR_TAG                 DescriptorTag;
>    UINT32                             PrevAllocationExtentDescriptor;
>    UINT32                             LengthOfAllocationDescriptors;
> @@ -235,6 +180,17 @@ typedef struct {
>  } UDF_VOLUME_DESCRIPTOR;
> 
>  typedef struct {
> +  UDF_DESCRIPTOR_TAG             DescriptorTag;
> +  UDF_TIMESTAMP                  RecordingDateTime;
> +  UINT32                         IntegrityType;
> +  UDF_EXTENT_AD                  NextIntegrityExtent;
> +  UINT8                          LogicalVolumeContentsUse[32];
> +  UINT32                         NumberOfPartitions;
> +  UINT32                         LengthOfImplementationUse;
> +  UINT8                          Data[0];
> +} UDF_LOGICAL_VOLUME_INTEGRITY;
> +
> +typedef struct {
>    UDF_DESCRIPTOR_TAG         DescriptorTag;
>    UINT32                     VolumeDescriptorSequenceNumber;
>    UINT16                     PartitionFlags;
> @@ -251,33 +207,6 @@ typedef struct {
> 
>  typedef struct {
>    UDF_DESCRIPTOR_TAG              DescriptorTag;
> -  UINT32                          VolumeDescriptorSequenceNumber;
> -  UDF_CHAR_SPEC                   DescriptorCharacterSet;
> -  UINT8                           LogicalVolumeIdentifier[128];
> -  UINT32                          LogicalBlockSize;
> -  UDF_ENTITY_ID                   DomainIdentifier;
> -  UDF_LONG_ALLOCATION_DESCRIPTOR  LogicalVolumeContentsUse;
> -  UINT32                          MapTableLength;
> -  UINT32                          NumberOfPartitionMaps;
> -  UDF_ENTITY_ID                   ImplementationIdentifier;
> -  UINT8                           ImplementationUse[128];
> -  UDF_EXTENT_AD                   IntegritySequenceExtent;
> -  UINT8                           PartitionMaps[6];
> -} UDF_LOGICAL_VOLUME_DESCRIPTOR;
> -
> -typedef struct {
> -  UDF_DESCRIPTOR_TAG             DescriptorTag;
> -  UDF_TIMESTAMP                  RecordingDateTime;
> -  UINT32                         IntegrityType;
> -  UDF_EXTENT_AD                  NextIntegrityExtent;
> -  UINT8                          LogicalVolumeContentsUse[32];
> -  UINT32                         NumberOfPartitions;
> -  UINT32                         LengthOfImplementationUse;
> -  UINT8                          Data[0];
> -} UDF_LOGICAL_VOLUME_INTEGRITY;
> -
> -typedef struct {
> -  UDF_DESCRIPTOR_TAG              DescriptorTag;
>    UDF_TIMESTAMP                   RecordingDateAndTime;
>    UINT16                          InterchangeLevel;
>    UINT16                          MaximumInterchangeLevel;
> @@ -389,12 +318,10 @@ typedef struct {
>  // UDF filesystem driver's private data
>  //
>  typedef struct {
> -  UDF_LOGICAL_VOLUME_DESCRIPTOR  **LogicalVolDescs;
> -  UINTN                          LogicalVolDescsNo;
> -  UDF_PARTITION_DESCRIPTOR       **PartitionDescs;
> -  UINTN                          PartitionDescsNo;
> -  UDF_FILE_SET_DESCRIPTOR        **FileSetDescs;
> -  UINTN                          FileSetDescsNo;
> +  UINT64                         MainVdsStartLocation;
> +  UDF_LOGICAL_VOLUME_DESCRIPTOR  LogicalVolDesc;
> +  UDF_PARTITION_DESCRIPTOR       PartitionDesc;
> +  UDF_FILE_SET_DESCRIPTOR        FileSetDesc;
>    UINTN                          FileEntrySize;
>  } UDF_VOLUME_INFO;
> 
> @@ -884,17 +811,6 @@ ResolveSymlink (
>    );
> 
>  /**
> -  Clean up in-memory UDF volume information.
> -
> -  @param[in] Volume Volume information pointer.
> -
> -**/
> -VOID
> -CleanupVolumeInformation (
> -  IN UDF_VOLUME_INFO *Volume
> -  );
> -
> -/**
>    Clean up in-memory UDF file information.
> 
>    @param[in] File File information pointer.
> --
> 2.11.0
> 
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Re: [edk2] [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix creation of UDF logical partition
Posted by Paulo Alcantara 7 years, 3 months ago

On September 21, 2017 5:49:19 AM GMT-03:00, "Zeng, Star" <star.zeng@intel.com> wrote:
>VS2015 Build-tested-by: Star Zeng <star.zeng@intel.com>
>
>I have a minor comment to this patch title, how about to use
>"MdeModulePkg/UDF: Fix creation of UDF logical partition" as this patch
>is touching both PartitionDxe and UdfDxe? Otherwise, you'd better to
>split this patch to two, one for PartitionDxe and one for UdfDxe.
>
>Since the patch could fix the issue we found, and if you agree my minor
>comment above, Reviewed-by: Star Zeng <star.zeng@intel.com>

Thank you all for the tests! Star, I agree with you. Could you please fix the title for me? Also, please add Laszlo's Build-tested-by in the series.

Thanks!
Paulo

>
>
>Thanks,
>Star
>-----Original Message-----
>From: Wu, Hao A 
>Sent: Thursday, September 21, 2017 4:09 PM
>To: Paulo Alcantara <pcacjr@zytor.com>; edk2-devel@lists.01.org
>Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Laszlo Ersek <lersek@redhat.com>;
>Dong, Eric <eric.dong@intel.com>; Zeng, Star <star.zeng@intel.com>
>Subject: RE: [edk2] [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix
>creation of UDF logical partition
>
>I did a simple test on a Windows8.1 installation DVD, and here's the
>result
>of a map command under shell:
>
>Before the patch:
>Mapping table
>      FS0: Alias(s):CD0f65535a1:;BLK2:
>          PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x5,0xFFFF,0x0)/CDROM(0x1)
>     BLK0: Alias(s):
>          PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x5,0xFFFF,0x0)
>     BLK1: Alias(s):
>          PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x5,0xFFFF,0x0)/CDROM(0x0)
>      FS1: Alias(s):CD0f65535ab:;BLK5:
>PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x5,0xFFFF,0x0)/VenMedia(C5BD4D42-1A76-4996-8956-73CDA326CD0A)/CDROM(0x1)
>     BLK3: Alias(s):
>PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x5,0xFFFF,0x0)/VenMedia(C5BD4D42-1A76-4996-8956-73CDA326CD0A)
>     BLK4: Alias(s):
>PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x5,0xFFFF,0x0)/VenMedia(C5BD4D42-1A76-4996-8956-73CDA326CD0A)/CDROM(0x0)
>
>After the patch:
>Mapping table
>      FS0: Alias(s):CD0f65535a1:;BLK2:
>          PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x5,0xFFFF,0x0)/CDROM(0x1)
>     BLK0: Alias(s):
>          PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x5,0xFFFF,0x0)
>     BLK1: Alias(s):
>          PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x5,0xFFFF,0x0)/CDROM(0x0)
>     BLK3: Alias(s):
>PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x5,0xFFFF,0x0)/VenMedia(C5BD4D42-1A76-4996-8956-73CDA326CD0A)
>
>
>Since the additional file system is gone:
>Tested-by: Hao Wu <hao.a.wu@intel.com>
>
>
>Best Regards,
>Hao Wu
>
>> -----Original Message-----
>> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf
>Of Paulo
>> Alcantara
>> Sent: Thursday, September 21, 2017 2:16 AM
>> To: edk2-devel@lists.01.org
>> Cc: Ni, Ruiyu; Laszlo Ersek; Dong, Eric; Zeng, Star
>> Subject: [edk2] [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix
>creation of
>> UDF logical partition
>> 
>> Do not reserve entire block device size for an UDF file system -
>> instead, reserve the appropriate space (UDF logical volume space) for
>> it.
>> 
>> Additionally, only create a logical partition for UDF logical volumes
>> that are currently supported by EDK2 UDF file system implementation.
>For
>> instance, an UDF volume with a single LVD and a single Physical (Type
>1)
>> Partition will be supported.
>> 
>> Cc: Eric Dong <eric.dong@intel.com>
>> Cc: Ruiyu Ni <ruiyu.ni@intel.com>
>> Cc: Star Zeng <star.zeng@intel.com>
>> Cc: Laszlo Ersek <lersek@redhat.com>
>> Reported-by: Ruiyu Ni <ruiyu.ni@intel.com>
>> Contributed-under: TianoCore Contribution Agreement 1.1
>> Signed-off-by: Paulo Alcantara <pcacjr@zytor.com>
>> ---
>>  MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c            | 363
>++++++++++--
>>  MdeModulePkg/Universal/Disk/UdfDxe/File.c                 |  16 +-
>>  MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c | 627
>> ++++++++------------
>>  MdeModulePkg/Universal/Disk/UdfDxe/Udf.c                  |   7 -
>>  MdeModulePkg/Universal/Disk/UdfDxe/Udf.h                  | 158
>++---
>>  5 files changed, 606 insertions(+), 565 deletions(-)
>> 
>> diff --git a/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
>> b/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
>> index 609f56cef6..572ba7a81a 100644
>> --- a/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
>> +++ b/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
>> @@ -64,11 +64,12 @@ FindAnchorVolumeDescriptorPointer (
>>    OUT  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint
>>    )
>>  {
>> -  EFI_STATUS  Status;
>> -  UINT32      BlockSize;
>> -  EFI_LBA     EndLBA;
>> -  EFI_LBA     DescriptorLBAs[4];
>> -  UINTN       Index;
>> +  EFI_STATUS          Status;
>> +  UINT32              BlockSize;
>> +  EFI_LBA             EndLBA;
>> +  EFI_LBA             DescriptorLBAs[4];
>> +  UINTN               Index;
>> +  UDF_DESCRIPTOR_TAG  *DescriptorTag;
>> 
>>    BlockSize = BlockIo->Media->BlockSize;
>>    EndLBA = BlockIo->Media->LastBlock;
>> @@ -88,10 +89,13 @@ FindAnchorVolumeDescriptorPointer (
>>      if (EFI_ERROR (Status)) {
>>        return Status;
>>      }
>> +
>> +    DescriptorTag = &AnchorPoint->DescriptorTag;
>> +
>>      //
>>      // Check if read LBA has a valid AVDP descriptor.
>>      //
>> -    if (IS_AVDP (AnchorPoint)) {
>> +    if (DescriptorTag->TagIdentifier ==
>UdfAnchorVolumeDescriptorPointer) {
>>        return EFI_SUCCESS;
>>      }
>>    }
>> @@ -102,23 +106,18 @@ FindAnchorVolumeDescriptorPointer (
>>  }
>> 
>>  /**
>> -  Check if block device supports a valid UDF file system as
>specified by OSTA
>> -  Universal Disk Format Specification 2.60.
>> +  Find UDF volume identifiers in a Volume Recognition Sequence.
>> 
>> -  @param[in]   BlockIo  BlockIo interface.
>> -  @param[in]   DiskIo   DiskIo interface.
>> +  @param[in]  BlockIo             BlockIo interface.
>> +  @param[in]  DiskIo              DiskIo interface.
>> 
>> -  @retval EFI_SUCCESS          UDF file system found.
>> -  @retval EFI_UNSUPPORTED      UDF file system not found.
>> -  @retval EFI_NO_MEDIA         The device has no media.
>> -  @retval EFI_DEVICE_ERROR     The device reported an error.
>> -  @retval EFI_VOLUME_CORRUPTED The file system structures are
>corrupted.
>> -  @retval EFI_OUT_OF_RESOURCES The scan was not successful due to
>lack of
>> -                               resources.
>> +  @retval EFI_SUCCESS             UDF volume identifiers were found.
>> +  @retval EFI_NOT_FOUND           UDF volume identifiers were not
>found.
>> +  @retval other                   Failed to perform disk I/O.
>> 
>>  **/
>>  EFI_STATUS
>> -SupportUdfFileSystem (
>> +FindUdfVolumeIdentifiers (
>>    IN EFI_BLOCK_IO_PROTOCOL  *BlockIo,
>>    IN EFI_DISK_IO_PROTOCOL   *DiskIo
>>    )
>> @@ -128,7 +127,6 @@ SupportUdfFileSystem (
>>    UINT64                                EndDiskOffset;
>>    CDROM_VOLUME_DESCRIPTOR               VolDescriptor;
>>    CDROM_VOLUME_DESCRIPTOR               TerminatingVolDescriptor;
>> -  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  AnchorPoint;
>> 
>>    ZeroMem ((VOID *)&TerminatingVolDescriptor, sizeof
>> (CDROM_VOLUME_DESCRIPTOR));
>> 
>> @@ -167,7 +165,7 @@ SupportUdfFileSystem (
>>          (CompareMem ((VOID *)&VolDescriptor,
>>                       (VOID *)&TerminatingVolDescriptor,
>>                       sizeof (CDROM_VOLUME_DESCRIPTOR)) == 0)) {
>> -      return EFI_UNSUPPORTED;
>> +      return EFI_NOT_FOUND;
>>      }
>>    }
>> 
>> @@ -176,7 +174,7 @@ SupportUdfFileSystem (
>>    //
>>    Offset += UDF_LOGICAL_SECTOR_SIZE;
>>    if (Offset >= EndDiskOffset) {
>> -    return EFI_UNSUPPORTED;
>> +    return EFI_NOT_FOUND;
>>    }
>> 
>>    Status = DiskIo->ReadDisk (
>> @@ -196,7 +194,7 @@ SupportUdfFileSystem (
>>        (CompareMem ((VOID *)VolDescriptor.Unknown.Id,
>>                     (VOID *)UDF_NSR3_IDENTIFIER,
>>                     sizeof (VolDescriptor.Unknown.Id)) != 0)) {
>> -    return EFI_UNSUPPORTED;
>> +    return EFI_NOT_FOUND;
>>    }
>> 
>>    //
>> @@ -204,7 +202,7 @@ SupportUdfFileSystem (
>>    //
>>    Offset += UDF_LOGICAL_SECTOR_SIZE;
>>    if (Offset >= EndDiskOffset) {
>> -    return EFI_UNSUPPORTED;
>> +    return EFI_NOT_FOUND;
>>    }
>> 
>>    Status = DiskIo->ReadDisk (
>> @@ -221,15 +219,291 @@ SupportUdfFileSystem (
>>    if (CompareMem ((VOID *)VolDescriptor.Unknown.Id,
>>                    (VOID *)UDF_TEA_IDENTIFIER,
>>                    sizeof (VolDescriptor.Unknown.Id)) != 0) {
>> -    return EFI_UNSUPPORTED;
>> +    return EFI_NOT_FOUND;
>> +  }
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +/**
>> +  Check if Logical Volume Descriptor is supported by current EDK2
>UDF file
>> +  system implementation.
>> +
>> +  @param[in]  LogicalVolDesc  Logical Volume Descriptor pointer.
>> +
>> +  @retval TRUE                Logical Volume Descriptor is
>supported.
>> +  @retval FALSE               Logical Volume Descriptor is not
>supported.
>> +
>> +**/
>> +BOOLEAN
>> +IsLogicalVolumeDescriptorSupported (
>> +  UDF_LOGICAL_VOLUME_DESCRIPTOR *LogicalVolDesc
>> +  )
>> +{
>> +  //
>> +  // Check for a valid UDF revision range
>> +  //
>> +  switch (UDF_LVD_REVISION (LogicalVolDesc)) {
>> +  case 0x0102:
>> +  case 0x0150:
>> +  case 0x0200:
>> +  case 0x0201:
>> +  case 0x0250:
>> +  case 0x0260:
>> +    break;
>> +  default:
>> +    return FALSE;
>> +  }
>> +
>> +  //
>> +  // Check for a single Partition Map
>> +  //
>> +  if (LogicalVolDesc->NumberOfPartitionMaps > 1) {
>> +    return FALSE;
>> +  }
>> +  //
>> +  // UDF 1.02 revision supports only Type 1 (Physical) partitions,
>but
>> +  // let's check it any way.
>> +  //
>> +  // PartitionMap[0] -> type
>> +  // PartitionMap[1] -> length (in bytes)
>> +  //
>> +  if (LogicalVolDesc->PartitionMaps[0] != 1 ||
>> +      LogicalVolDesc->PartitionMaps[1] != 6) {
>> +    return FALSE;
>> +  }
>> +
>> +  return TRUE;
>> +}
>> +
>> +/**
>> +  Find UDF logical volume location and whether it is supported by
>current
>> EDK2
>> +  UDF file system implementation.
>> +
>> +  @param[in]  BlockIo             BlockIo interface.
>> +  @param[in]  DiskIo              DiskIo interface.
>> +  @param[in]  AnchorPoint         Anchor volume descriptor pointer.
>> +  @param[out] MainVdsStartBlock   Main VDS starting block number.
>> +  @param[out] MainVdsEndBlock     Main VDS ending block number.
>> +
>> +  @retval EFI_SUCCESS             UDF logical volume was found.
>> +  @retval EFI_VOLUME_CORRUPTED    UDF file system structures are
>> corrupted.
>> +  @retval EFI_UNSUPPORTED         UDF logical volume is not
>supported.
>> +  @retval other                   Failed to perform disk I/O.
>> +
>> +**/
>> +EFI_STATUS
>> +FindLogicalVolumeLocation (
>> +  IN   EFI_BLOCK_IO_PROTOCOL                 *BlockIo,
>> +  IN   EFI_DISK_IO_PROTOCOL                  *DiskIo,
>> +  IN   UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint,
>> +  OUT  UINT64                                *MainVdsStartBlock,
>> +  OUT  UINT64                                *MainVdsEndBlock
>> +  )
>> +{
>> +  EFI_STATUS                     Status;
>> +  UINT32                         BlockSize;
>> +  EFI_LBA                        LastBlock;
>> +  UDF_EXTENT_AD                  *ExtentAd;
>> +  UINT64                         SeqBlocksNum;
>> +  UINT64                         SeqStartBlock;
>> +  UINT64                         GuardMainVdsStartBlock;
>> +  VOID                           *Buffer;
>> +  UINT64                         SeqEndBlock;
>> +  BOOLEAN                        StopSequence;
>> +  UINTN                          LvdsCount;
>> +  UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;
>> +  UDF_DESCRIPTOR_TAG             *DescriptorTag;
>> +
>> +  BlockSize = BlockIo->Media->BlockSize;
>> +  LastBlock = BlockIo->Media->LastBlock;
>> +  ExtentAd = &AnchorPoint->MainVolumeDescriptorSequenceExtent;
>> +
>> +  //
>> +  // UDF 2.60, 2.2.3.1 struct MainVolumeDescriptorSequenceExtent
>> +  //
>> +  // The Main Volume Descriptor Sequence Extent shall have a minimum
>> length of
>> +  // 16 logical sectors.
>> +  //
>> +  // Also make sure it does not exceed maximum number of blocks in
>the disk.
>> +  //
>> +  SeqBlocksNum = DivU64x32 ((UINT64)ExtentAd->ExtentLength,
>BlockSize);
>> +  if (SeqBlocksNum < 16 || (EFI_LBA)SeqBlocksNum > LastBlock + 1) {
>> +    return EFI_VOLUME_CORRUPTED;
>> +  }
>> +
>> +  //
>> +  // Check for valid Volume Descriptor Sequence starting block
>number
>> +  //
>> +  SeqStartBlock = (UINT64)ExtentAd->ExtentLocation;
>> +  if (SeqStartBlock > LastBlock ||
>> +      SeqStartBlock + SeqBlocksNum - 1 > LastBlock) {
>> +    return EFI_VOLUME_CORRUPTED;
>>    }
>> 
>> +  GuardMainVdsStartBlock = SeqStartBlock;
>> +
>> +  //
>> +  // Allocate buffer for reading disk blocks
>> +  //
>> +  Buffer = AllocateZeroPool ((UINTN)BlockSize);
>> +  if (Buffer == NULL) {
>> +    return EFI_OUT_OF_RESOURCES;
>> +  }
>> +
>> +  SeqEndBlock = SeqStartBlock + SeqBlocksNum;
>> +  StopSequence = FALSE;
>> +  LvdsCount = 0;
>> +  Status = EFI_VOLUME_CORRUPTED;
>> +  //
>> +  // Start Main Volume Descriptor Sequence
>> +  //
>> +  for (; SeqStartBlock < SeqEndBlock && !StopSequence;
>SeqStartBlock++) {
>> +    //
>> +    // Read disk block
>> +    //
>> +    Status = BlockIo->ReadBlocks (
>> +      BlockIo,
>> +      BlockIo->Media->MediaId,
>> +      SeqStartBlock,
>> +      BlockSize,
>> +      Buffer
>> +      );
>> +    if (EFI_ERROR (Status)) {
>> +      goto Out_Free;
>> +    }
>> +
>> +    DescriptorTag = Buffer;
>> +
>> +    //
>> +    // ECMA 167, 8.4.1 Contents of a Volume Descriptor Sequence
>> +    //
>> +    // - A Volume Descriptor Sequence shall contain one or more
>Primary
>> Volume
>> +    //   Descriptors.
>> +    // - A Volume Descriptor Sequence shall contain zero or more
>> Implementation
>> +    //   Use Volume Descriptors.
>> +    // - A Volume Descriptor Sequence shall contain zero or more
>Partition
>> +    //   Descriptors.
>> +    // - A Volume Descriptor Sequence shall contain zero or more
>Logical
>> Volume
>> +    //   Descriptors.
>> +    // - A Volume Descriptor Sequence shall contain zero or more
>Unallocated
>> +    //   Space Descriptors.
>> +    //
>> +    switch (UDF_TAG_ID (DescriptorTag)) {
>> +    case UdfPrimaryVolumeDescriptor:
>> +    case UdfImplemenationUseVolumeDescriptor:
>> +    case UdfPartitionDescriptor:
>> +    case UdfUnallocatedSpaceDescriptor:
>> +      break;
>> +
>> +    case UdfLogicalVolumeDescriptor:
>> +      LogicalVolDesc = Buffer;
>> +
>> +      //
>> +      // Check for existence of a single LVD and whether it is
>supported by
>> +      // current EDK2 UDF file system implementation.
>> +      //
>> +      if (++LvdsCount > 1 ||
>> +          !IsLogicalVolumeDescriptorSupported (LogicalVolDesc)) {
>> +        Status = EFI_UNSUPPORTED;
>> +        StopSequence = TRUE;
>> +      }
>> +
>> +      break;
>> +
>> +    case UdfTerminatingDescriptor:
>> +      //
>> +      // Stop the sequence when we find a Terminating Descriptor
>> +      // (aka Unallocated Sector), se we don't have to walk all the
>unallocated
>> +      // area unnecessarily.
>> +      //
>> +      StopSequence = TRUE;
>> +      break;
>> +
>> +    default:
>> +      //
>> +      // An invalid Volume Descriptor has been found in the sequece.
>Volume is
>> +      // corrupted.
>> +      //
>> +      Status = EFI_VOLUME_CORRUPTED;
>> +      goto Out_Free;
>> +    }
>> +  }
>> +
>> +  //
>> +  // Check if LVD was found
>> +  //
>> +  if (!EFI_ERROR (Status) && LvdsCount == 1) {
>> +    *MainVdsStartBlock = GuardMainVdsStartBlock;
>> +    //
>> +    // We do not need to read either LVD or PD descriptors to know
>the last
>> +    // valid block in the found UDF file system. It's already
>LastBlock.
>> +    //
>> +    *MainVdsEndBlock = LastBlock;
>> +
>> +    Status = EFI_SUCCESS;
>> +  }
>> +
>> +Out_Free:
>> +  //
>> +  // Free block read buffer
>> +  //
>> +  FreePool (Buffer);
>> +
>> +  return Status;
>> +}
>> +
>> +/**
>> +  Find a supported UDF file system in block device.
>> +
>> +  @param[in]  BlockIo             BlockIo interface.
>> +  @param[in]  DiskIo              DiskIo interface.
>> +  @param[out] StartingLBA         UDF file system starting LBA.
>> +  @param[out] EndingLBA           UDF file system starting LBA.
>> +
>> +  @retval EFI_SUCCESS             UDF file system was found.
>> +  @retval other                   UDF file system was not found.
>> +
>> +**/
>> +EFI_STATUS
>> +FindUdfFileSystem (
>> +  IN EFI_BLOCK_IO_PROTOCOL  *BlockIo,
>> +  IN EFI_DISK_IO_PROTOCOL   *DiskIo,
>> +  OUT EFI_LBA               *StartingLBA,
>> +  OUT EFI_LBA               *EndingLBA
>> +  )
>> +{
>> +  EFI_STATUS Status;
>> +  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  AnchorPoint;
>> +
>> +  //
>> +  // Find UDF volume identifiers
>> +  //
>> +  Status = FindUdfVolumeIdentifiers (BlockIo, DiskIo);
>> +  if (EFI_ERROR (Status)) {
>> +    return Status;
>> +  }
>> +
>> +  //
>> +  // Find Anchor Volume Descriptor Pointer
>> +  //
>>    Status = FindAnchorVolumeDescriptorPointer (BlockIo, DiskIo,
>&AnchorPoint);
>>    if (EFI_ERROR (Status)) {
>> -    return EFI_UNSUPPORTED;
>> +    return Status;
>>    }
>> 
>> -  return EFI_SUCCESS;
>> +  //
>> +  // Find Logical Volume location
>> +  //
>> +  Status = FindLogicalVolumeLocation (
>> +    BlockIo,
>> +    DiskIo,
>> +    &AnchorPoint,
>> +    (UINT64 *)StartingLBA,
>> +    (UINT64 *)EndingLBA
>> +    );
>> +
>> +  return Status;
>>  }
>> 
>>  /**
>> @@ -263,9 +537,9 @@ PartitionInstallUdfChildHandles (
>>    UINT32                       RemainderByMediaBlockSize;
>>    EFI_STATUS                   Status;
>>    EFI_BLOCK_IO_MEDIA           *Media;
>> -  EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode;
>> -  EFI_GUID                     *VendorDefinedGuid;
>>    EFI_PARTITION_INFO_PROTOCOL  PartitionInfo;
>> +  EFI_LBA                      StartingLBA;
>> +  EFI_LBA                      EndingLBA;
>> 
>>    Media = BlockIo->Media;
>> 
>> @@ -281,35 +555,10 @@ PartitionInstallUdfChildHandles (
>>      return EFI_NOT_FOUND;
>>    }
>> 
>> -  DevicePathNode = DevicePath;
>> -  while (!IsDevicePathEnd (DevicePathNode)) {
>> -    //
>> -    // Do not allow checking for UDF file systems in CDROM "El
>Torito"
>> -    // partitions, and skip duplicate installation of UDF file
>system child
>> -    // nodes.
>> -    //
>> -    if (DevicePathType (DevicePathNode) == MEDIA_DEVICE_PATH) {
>> -      if (DevicePathSubType (DevicePathNode) == MEDIA_CDROM_DP) {
>> -        return EFI_NOT_FOUND;
>> -      }
>> -      if (DevicePathSubType (DevicePathNode) == MEDIA_VENDOR_DP) {
>> -        VendorDefinedGuid = (EFI_GUID *)((UINTN)DevicePathNode +
>> -                                         OFFSET_OF
>(VENDOR_DEVICE_PATH, Guid));
>> -        if (CompareGuid (VendorDefinedGuid, &gUdfDevPathGuid)) {
>> -          return EFI_NOT_FOUND;
>> -        }
>> -      }
>> -    }
>> -    //
>> -    // Try next device path node
>> -    //
>> -    DevicePathNode = NextDevicePathNode (DevicePathNode);
>> -  }
>> -
>>    //
>> -  // Check if block device supports an UDF file system
>> +  // Search for an UDF file system on block device
>>    //
>> -  Status = SupportUdfFileSystem (BlockIo, DiskIo);
>> +  Status = FindUdfFileSystem (BlockIo, DiskIo, &StartingLBA,
>&EndingLBA);
>>    if (EFI_ERROR (Status)) {
>>      return EFI_NOT_FOUND;
>>    }
>> @@ -334,8 +583,8 @@ PartitionInstallUdfChildHandles (
>>      DevicePath,
>>      (EFI_DEVICE_PATH_PROTOCOL *)&gUdfDevicePath,
>>      &PartitionInfo,
>> -    0,
>> -    Media->LastBlock,
>> +    StartingLBA,
>> +    EndingLBA,
>>      Media->BlockSize
>>      );
>>    if (!EFI_ERROR (Status)) {
>> diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/File.c
>> b/MdeModulePkg/Universal/Disk/UdfDxe/File.c
>> index 625f2c5637..6f07bf2066 100644
>> --- a/MdeModulePkg/Universal/Disk/UdfDxe/File.c
>> +++ b/MdeModulePkg/Universal/Disk/UdfDxe/File.c
>> @@ -131,7 +131,6 @@ Error_Alloc_Priv_File_Data:
>>    CleanupFileInformation (&PrivFsData->Root);
>> 
>>  Error_Find_Root_Dir:
>> -  CleanupVolumeInformation (&PrivFsData->Volume);
>> 
>>  Error_Read_Udf_Volume:
>>  Error_Invalid_Params:
>> @@ -429,7 +428,7 @@ UdfRead (
>>      }
>>      ASSERT (NewFileEntryData != NULL);
>> 
>> -    if (IS_FE_SYMLINK (NewFileEntryData)) {
>> +    if (FE_ICB_FILE_TYPE (NewFileEntryData) == UdfFileEntrySymlink)
>{
>>        Status = ResolveSymlink (
>>          BlockIo,
>>          DiskIo,
>> @@ -529,7 +528,6 @@ UdfClose (
>>    EFI_TPL                     OldTpl;
>>    EFI_STATUS                  Status;
>>    PRIVATE_UDF_FILE_DATA       *PrivFileData;
>> -  PRIVATE_UDF_SIMPLE_FS_DATA  *PrivFsData;
>> 
>>    OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
>> 
>> @@ -542,8 +540,6 @@ UdfClose (
>> 
>>    PrivFileData = PRIVATE_UDF_FILE_DATA_FROM_THIS (This);
>> 
>> -  PrivFsData = PRIVATE_UDF_SIMPLE_FS_DATA_FROM_THIS (PrivFileData-
>> >SimpleFs);
>> -
>>    if (!PrivFileData->IsRootDirectory) {
>>      CleanupFileInformation (&PrivFileData->File);
>> 
>> @@ -552,10 +548,6 @@ UdfClose (
>>      }
>>    }
>> 
>> -  if (--PrivFsData->OpenFiles == 0) {
>> -    CleanupVolumeInformation (&PrivFsData->Volume);
>> -  }
>> -
>>    FreePool ((VOID *)PrivFileData);
>> 
>>  Exit:
>> @@ -652,7 +644,7 @@ UdfGetPosition (
>>    // As per UEFI spec, if the file handle is a directory, then the
>current file
>>    // position has no meaning and the operation is not supported.
>>    //
>> -  if (IS_FID_DIRECTORY_FILE
>(&PrivFileData->File.FileIdentifierDesc)) {
>> +  if (IS_FID_DIRECTORY_FILE (PrivFileData->File.FileIdentifierDesc))
>{
>>      return  EFI_UNSUPPORTED;
>>    }
>> 
>> @@ -788,7 +780,7 @@ UdfGetInfo (
>>    } else if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid))
>{
>>      String = VolumeLabel;
>> 
>> -    FileSetDesc = PrivFsData->Volume.FileSetDescs[0];
>> +    FileSetDesc = &PrivFsData->Volume.FileSetDesc;
>> 
>>      OstaCompressed = &FileSetDesc->LogicalVolumeIdentifier[0];
>> 
>> @@ -847,7 +839,7 @@ UdfGetInfo (
>>      FileSystemInfo->Size        = FileSystemInfoLength;
>>      FileSystemInfo->ReadOnly    = TRUE;
>>      FileSystemInfo->BlockSize   =
>> -      LV_BLOCK_SIZE (&PrivFsData->Volume, UDF_DEFAULT_LV_NUM);
>> +      PrivFsData->Volume.LogicalVolDesc.LogicalBlockSize;
>>      FileSystemInfo->VolumeSize  = VolumeSize;
>>      FileSystemInfo->FreeSpace   = FreeSpaceSize;
>> 
>> diff --git
>a/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
>> b/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
>> index 5df267761f..62d817989f 100644
>> --- a/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
>> +++ b/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
>> @@ -38,11 +38,12 @@ FindAnchorVolumeDescriptorPointer (
>>    OUT  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint
>>    )
>>  {
>> -  EFI_STATUS  Status;
>> -  UINT32      BlockSize;
>> -  EFI_LBA     EndLBA;
>> -  EFI_LBA     DescriptorLBAs[4];
>> -  UINTN       Index;
>> +  EFI_STATUS          Status;
>> +  UINT32              BlockSize;
>> +  EFI_LBA             EndLBA;
>> +  EFI_LBA             DescriptorLBAs[4];
>> +  UINTN               Index;
>> +  UDF_DESCRIPTOR_TAG  *DescriptorTag;
>> 
>>    BlockSize = BlockIo->Media->BlockSize;
>>    EndLBA = BlockIo->Media->LastBlock;
>> @@ -62,10 +63,13 @@ FindAnchorVolumeDescriptorPointer (
>>      if (EFI_ERROR (Status)) {
>>        return Status;
>>      }
>> +
>> +    DescriptorTag = &AnchorPoint->DescriptorTag;
>> +
>>      //
>>      // Check if read LBA has a valid AVDP descriptor.
>>      //
>> -    if (IS_AVDP (AnchorPoint)) {
>> +    if (DescriptorTag->TagIdentifier ==
>UdfAnchorVolumeDescriptorPointer) {
>>        return EFI_SUCCESS;
>>      }
>>    }
>> @@ -99,148 +103,98 @@ StartMainVolumeDescriptorSequence (
>>    OUT  UDF_VOLUME_INFO                       *Volume
>>    )
>>  {
>> -  EFI_STATUS                     Status;
>> -  UINT32                         BlockSize;
>> -  UDF_EXTENT_AD                  *ExtentAd;
>> -  UINT64                         StartingLsn;
>> -  UINT64                         EndingLsn;
>> -  VOID                           *Buffer;
>> -  UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;
>> -  UDF_PARTITION_DESCRIPTOR       *PartitionDesc;
>> -  UINTN                          Index;
>> -  UINT32                         LogicalBlockSize;
>> +  EFI_STATUS            Status;
>> +  UINT32                BlockSize;
>> +  UDF_EXTENT_AD         *ExtentAd;
>> +  EFI_LBA               SeqStartBlock;
>> +  EFI_LBA               SeqEndBlock;
>> +  BOOLEAN               StopSequence;
>> +  VOID                  *Buffer;
>> +  UDF_DESCRIPTOR_TAG    *DescriptorTag;
>> +  UINT32                LogicalBlockSize;
>> +
>> +  BlockSize = BlockIo->Media->BlockSize;
>> +  ExtentAd = &AnchorPoint->MainVolumeDescriptorSequenceExtent;
>> 
>>    //
>> -  // We've already found an ADVP on the volume. It contains the
>extent
>> -  // (MainVolumeDescriptorSequenceExtent) where the Main Volume
>> Descriptor
>> -  // Sequence starts. Therefore, we'll look for Logical Volume
>Descriptors and
>> -  // Partitions Descriptors and save them in memory, accordingly.
>> -  //
>> -  // Note also that each descriptor will be aligned on a block size
>(BlockSize)
>> -  // boundary, so we need to read one block at a time.
>> +  // Allocate buffer for reading disk blocks
>>    //
>> -  BlockSize    = BlockIo->Media->BlockSize;
>> -  ExtentAd     = &AnchorPoint->MainVolumeDescriptorSequenceExtent;
>> -  StartingLsn  = (UINT64)ExtentAd->ExtentLocation;
>> -  EndingLsn    = StartingLsn + DivU64x32 (
>> -                                     (UINT64)ExtentAd->ExtentLength,
>> -                                     BlockSize
>> -                                     );
>> -
>> -  Volume->LogicalVolDescs =
>> -    (UDF_LOGICAL_VOLUME_DESCRIPTOR **)AllocateZeroPool (ExtentAd-
>> >ExtentLength);
>> -  if (Volume->LogicalVolDescs == NULL) {
>> -    return EFI_OUT_OF_RESOURCES;
>> -  }
>> -
>> -  Volume->PartitionDescs =
>> -    (UDF_PARTITION_DESCRIPTOR **)AllocateZeroPool (ExtentAd-
>> >ExtentLength);
>> -  if (Volume->PartitionDescs == NULL) {
>> -    Status = EFI_OUT_OF_RESOURCES;
>> -    goto Error_Alloc_Pds;
>> -  }
>> -
>> -  Buffer = AllocateZeroPool (BlockSize);
>> +  Buffer = AllocateZeroPool ((UINTN)BlockSize);
>>    if (Buffer == NULL) {
>> -    Status = EFI_OUT_OF_RESOURCES;
>> -    goto Error_Alloc_Buf;
>> +    return EFI_OUT_OF_RESOURCES;
>>    }
>> 
>> -  Volume->LogicalVolDescsNo  = 0;
>> -  Volume->PartitionDescsNo   = 0;
>> -
>> -  while (StartingLsn <= EndingLsn) {
>> -    Status = DiskIo->ReadDisk (
>> -      DiskIo,
>> +  //
>> +  // The logical partition created by Partition driver is relative
>to the main
>> +  // VDS extent location, so we start the Main Volume Descriptor
>Sequence at
>> +  // LBA 0.
>> +  //
>> +  // We don't need to check again if we have valid Volume
>Descriptors here
>> since
>> +  // Partition driver already did.
>> +  //
>> +  SeqStartBlock = 0;
>> +  SeqEndBlock = SeqStartBlock + DivU64x32
>((UINT64)ExtentAd->ExtentLength,
>> +                                           BlockSize);
>> +  StopSequence = FALSE;
>> +  for (; SeqStartBlock < SeqEndBlock && !StopSequence;
>SeqStartBlock++) {
>> +    //
>> +    // Read disk block
>> +    //
>> +    Status = BlockIo->ReadBlocks (
>> +      BlockIo,
>>        BlockIo->Media->MediaId,
>> -      MultU64x32 (StartingLsn, BlockSize),
>> +      SeqStartBlock,
>>        BlockSize,
>>        Buffer
>>        );
>>      if (EFI_ERROR (Status)) {
>> -      goto Error_Read_Disk_Blk;
>> +      goto Out_Free;
>>      }
>> 
>> -    if (IS_TD (Buffer)) {
>> +    DescriptorTag = Buffer;
>> +
>> +    switch (UDF_TAG_ID (DescriptorTag)) {
>> +    case UdfPartitionDescriptor:
>>        //
>> -      // Found a Terminating Descriptor. Stop the sequence then.
>> +      // Save Partition Descriptor
>>        //
>> +      CopyMem (&Volume->PartitionDesc, Buffer, sizeof (Volume-
>> >PartitionDesc));
>>        break;
>> -    }
>> 
>> -    if (IS_LVD (Buffer)) {
>> +    case UdfLogicalVolumeDescriptor:
>>        //
>> -      // Found a Logical Volume Descriptor.
>> +      // Save Logical Volume Descriptor
>>        //
>> -      LogicalVolDesc =
>> -        (UDF_LOGICAL_VOLUME_DESCRIPTOR *)
>> -        AllocateZeroPool (sizeof (UDF_LOGICAL_VOLUME_DESCRIPTOR));
>> -      if (LogicalVolDesc == NULL) {
>> -        Status = EFI_OUT_OF_RESOURCES;
>> -        goto Error_Alloc_Lvd;
>> -      }
>> +      CopyMem (&Volume->LogicalVolDesc, Buffer, sizeof (Volume-
>> >LogicalVolDesc));
>> +      break;
>> 
>> -      CopyMem ((VOID *)LogicalVolDesc, Buffer,
>> -               sizeof (UDF_LOGICAL_VOLUME_DESCRIPTOR));
>> -      Volume->LogicalVolDescs[Volume->LogicalVolDescsNo++] =
>> LogicalVolDesc;
>> -    } else if (IS_PD (Buffer)) {
>> -      //
>> -      // Found a Partition Descriptor.
>> -      //
>> -      PartitionDesc =
>> -        (UDF_PARTITION_DESCRIPTOR *)
>> -        AllocateZeroPool (sizeof (UDF_PARTITION_DESCRIPTOR));
>> -      if (PartitionDesc == NULL) {
>> -        Status = EFI_OUT_OF_RESOURCES;
>> -        goto Error_Alloc_Pd;
>> -      }
>> +    case UdfTerminatingDescriptor:
>> +      StopSequence = TRUE;
>> +      break;
>> 
>> -      CopyMem ((VOID *)PartitionDesc, Buffer,
>> -               sizeof (UDF_PARTITION_DESCRIPTOR));
>> -      Volume->PartitionDescs[Volume->PartitionDescsNo++] =
>PartitionDesc;
>> +    default:
>> +      ;
>>      }
>> -
>> -    StartingLsn++;
>>    }
>> 
>>    //
>> -  // When an UDF volume (revision 2.00 or higher) contains a File
>Entry rather
>> -  // than an Extended File Entry (which is not recommended as per
>spec), we
>> need
>> -  // to make sure the size of a FE will be _at least_ 2048
>> -  // (UDF_LOGICAL_SECTOR_SIZE) bytes long to keep backward
>compatibility.
>> +  // Determine FE (File Entry) size
>>    //
>> -  LogicalBlockSize = LV_BLOCK_SIZE (Volume, UDF_DEFAULT_LV_NUM);
>> +  LogicalBlockSize = Volume->LogicalVolDesc.LogicalBlockSize;
>>    if (LogicalBlockSize >= UDF_LOGICAL_SECTOR_SIZE) {
>> -    Volume->FileEntrySize = LogicalBlockSize;
>> +    Volume->FileEntrySize = (UINTN)LogicalBlockSize;
>>    } else {
>>      Volume->FileEntrySize = UDF_LOGICAL_SECTOR_SIZE;
>>    }
>> 
>> -  FreePool (Buffer);
>> +  Status = EFI_SUCCESS;
>> 
>> -  return EFI_SUCCESS;
>> -
>> -Error_Alloc_Pd:
>> -Error_Alloc_Lvd:
>> -  for (Index = 0; Index < Volume->PartitionDescsNo; Index++) {
>> -    FreePool ((VOID *)Volume->PartitionDescs[Index]);
>> -  }
>> -
>> -  for (Index = 0; Index < Volume->LogicalVolDescsNo; Index++) {
>> -    FreePool ((VOID *)Volume->LogicalVolDescs[Index]);
>> -  }
>> -
>> -Error_Read_Disk_Blk:
>> +Out_Free:
>> +  //
>> +  // Free block read buffer
>> +  //
>>    FreePool (Buffer);
>> 
>> -Error_Alloc_Buf:
>> -  FreePool ((VOID *)Volume->PartitionDescs);
>> -  Volume->PartitionDescs = NULL;
>> -
>> -Error_Alloc_Pds:
>> -  FreePool ((VOID *)Volume->LogicalVolDescs);
>> -  Volume->LogicalVolDescs = NULL;
>> -
>>    return Status;
>>  }
>> 
>> @@ -262,48 +216,53 @@ GetPdFromLongAd (
>>    )
>>  {
>>    UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;
>> -  UINTN                          Index;
>> -  UDF_PARTITION_DESCRIPTOR       *PartitionDesc;
>>    UINT16                         PartitionNum;
>> 
>> -  LogicalVolDesc = Volume->LogicalVolDescs[UDF_DEFAULT_LV_NUM];
>> +  LogicalVolDesc = &Volume->LogicalVolDesc;
>> 
>> -  switch (LV_UDF_REVISION (LogicalVolDesc)) {
>> +  switch (UDF_LVD_REVISION (LogicalVolDesc)) {
>>    case 0x0102:
>> +  case 0x0150:
>> +  case 0x0200:
>> +  case 0x0201:
>> +  case 0x0250:
>> +  case 0x0260:
>>      //
>> -    // As per UDF 1.02 specification:
>> +    // UDF 1.02 specification:
>>      //
>>      // There shall be exactly one prevailing Logical Volume
>Descriptor recorded
>>      // per Volume Set. The Partition Maps field shall contain only
>Type 1
>>      // Partition Maps.
>>      //
>> -    PartitionNum = *(UINT16
>*)((UINTN)&LogicalVolDesc->PartitionMaps[4]);
>> -    break;
>> -  case 0x0150:
>> +    // UDF 1.50 through 2.60 specs say:
>>      //
>> -    // Ensure Type 1 Partition map. Other types aren't supported in
>this
>> -    // implementation.
>> +    // For the purpose of interchange partition maps shall be
>limited to
>> +    // Partition Map type 1, except type 2 maps as described in the
>document.
>> +    //
>> +    // NOTE: Only one Type 1 (Physical) Partition is supported. It
>has been
>> +    // checked already in Partition driver for existence of a single
>Type 1
>> +    // Partition map, so we don't have to double check here.
>> +    //
>> +    // Partition reference number can also be retrieved from
>> +    // LongAd->ExtentLocation.PartitionReferenceNumber, however the
>spec
>> says
>> +    // it may be 0, so let's not rely on it.
>>      //
>> -    if (LogicalVolDesc->PartitionMaps[0] != 1 ||
>> -        LogicalVolDesc->PartitionMaps[1] != 6) {
>> -      return NULL;
>> -    }
>>      PartitionNum = *(UINT16
>*)((UINTN)&LogicalVolDesc->PartitionMaps[4]);
>>      break;
>> -  case 0x0260:
>> +
>> +  default:
>>      //
>> 

-- 
Sent from my Android device with K-9 Mail. Please excuse my brevity.
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Re: [edk2] [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix creation of UDF logical partition
Posted by Wu, Hao A 7 years, 3 months ago
One small comment, within function PartitionInstallUdfChildHandles():

  ...
  //
  // Install partition child handle for UDF file system
  //
  Status = PartitionInstallChildHandle (
    ...
    );
  if (!EFI_ERROR (Status)) {  <----- Is this a typo? "if (EFI_ERROR (Status)) {"  
    Status = EFI_NOT_FOUND;
  }
  

Best Regards,
Hao Wu


> -----Original Message-----
> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of Paulo
> Alcantara
> Sent: Thursday, September 21, 2017 2:16 AM
> To: edk2-devel@lists.01.org
> Cc: Ni, Ruiyu; Laszlo Ersek; Dong, Eric; Zeng, Star
> Subject: [edk2] [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix creation of
> UDF logical partition
> 
> Do not reserve entire block device size for an UDF file system -
> instead, reserve the appropriate space (UDF logical volume space) for
> it.
> 
> Additionally, only create a logical partition for UDF logical volumes
> that are currently supported by EDK2 UDF file system implementation. For
> instance, an UDF volume with a single LVD and a single Physical (Type 1)
> Partition will be supported.
> 
> Cc: Eric Dong <eric.dong@intel.com>
> Cc: Ruiyu Ni <ruiyu.ni@intel.com>
> Cc: Star Zeng <star.zeng@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Reported-by: Ruiyu Ni <ruiyu.ni@intel.com>
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Paulo Alcantara <pcacjr@zytor.com>
> ---
>  MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c            | 363 ++++++++++--
>  MdeModulePkg/Universal/Disk/UdfDxe/File.c                 |  16 +-
>  MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c | 627
> ++++++++------------
>  MdeModulePkg/Universal/Disk/UdfDxe/Udf.c                  |   7 -
>  MdeModulePkg/Universal/Disk/UdfDxe/Udf.h                  | 158 ++---
>  5 files changed, 606 insertions(+), 565 deletions(-)
> 
> diff --git a/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
> b/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
> index 609f56cef6..572ba7a81a 100644
> --- a/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
> +++ b/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
> @@ -64,11 +64,12 @@ FindAnchorVolumeDescriptorPointer (
>    OUT  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint
>    )
>  {
> -  EFI_STATUS  Status;
> -  UINT32      BlockSize;
> -  EFI_LBA     EndLBA;
> -  EFI_LBA     DescriptorLBAs[4];
> -  UINTN       Index;
> +  EFI_STATUS          Status;
> +  UINT32              BlockSize;
> +  EFI_LBA             EndLBA;
> +  EFI_LBA             DescriptorLBAs[4];
> +  UINTN               Index;
> +  UDF_DESCRIPTOR_TAG  *DescriptorTag;
> 
>    BlockSize = BlockIo->Media->BlockSize;
>    EndLBA = BlockIo->Media->LastBlock;
> @@ -88,10 +89,13 @@ FindAnchorVolumeDescriptorPointer (
>      if (EFI_ERROR (Status)) {
>        return Status;
>      }
> +
> +    DescriptorTag = &AnchorPoint->DescriptorTag;
> +
>      //
>      // Check if read LBA has a valid AVDP descriptor.
>      //
> -    if (IS_AVDP (AnchorPoint)) {
> +    if (DescriptorTag->TagIdentifier == UdfAnchorVolumeDescriptorPointer) {
>        return EFI_SUCCESS;
>      }
>    }
> @@ -102,23 +106,18 @@ FindAnchorVolumeDescriptorPointer (
>  }
> 
>  /**
> -  Check if block device supports a valid UDF file system as specified by OSTA
> -  Universal Disk Format Specification 2.60.
> +  Find UDF volume identifiers in a Volume Recognition Sequence.
> 
> -  @param[in]   BlockIo  BlockIo interface.
> -  @param[in]   DiskIo   DiskIo interface.
> +  @param[in]  BlockIo             BlockIo interface.
> +  @param[in]  DiskIo              DiskIo interface.
> 
> -  @retval EFI_SUCCESS          UDF file system found.
> -  @retval EFI_UNSUPPORTED      UDF file system not found.
> -  @retval EFI_NO_MEDIA         The device has no media.
> -  @retval EFI_DEVICE_ERROR     The device reported an error.
> -  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
> -  @retval EFI_OUT_OF_RESOURCES The scan was not successful due to lack of
> -                               resources.
> +  @retval EFI_SUCCESS             UDF volume identifiers were found.
> +  @retval EFI_NOT_FOUND           UDF volume identifiers were not found.
> +  @retval other                   Failed to perform disk I/O.
> 
>  **/
>  EFI_STATUS
> -SupportUdfFileSystem (
> +FindUdfVolumeIdentifiers (
>    IN EFI_BLOCK_IO_PROTOCOL  *BlockIo,
>    IN EFI_DISK_IO_PROTOCOL   *DiskIo
>    )
> @@ -128,7 +127,6 @@ SupportUdfFileSystem (
>    UINT64                                EndDiskOffset;
>    CDROM_VOLUME_DESCRIPTOR               VolDescriptor;
>    CDROM_VOLUME_DESCRIPTOR               TerminatingVolDescriptor;
> -  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  AnchorPoint;
> 
>    ZeroMem ((VOID *)&TerminatingVolDescriptor, sizeof
> (CDROM_VOLUME_DESCRIPTOR));
> 
> @@ -167,7 +165,7 @@ SupportUdfFileSystem (
>          (CompareMem ((VOID *)&VolDescriptor,
>                       (VOID *)&TerminatingVolDescriptor,
>                       sizeof (CDROM_VOLUME_DESCRIPTOR)) == 0)) {
> -      return EFI_UNSUPPORTED;
> +      return EFI_NOT_FOUND;
>      }
>    }
> 
> @@ -176,7 +174,7 @@ SupportUdfFileSystem (
>    //
>    Offset += UDF_LOGICAL_SECTOR_SIZE;
>    if (Offset >= EndDiskOffset) {
> -    return EFI_UNSUPPORTED;
> +    return EFI_NOT_FOUND;
>    }
> 
>    Status = DiskIo->ReadDisk (
> @@ -196,7 +194,7 @@ SupportUdfFileSystem (
>        (CompareMem ((VOID *)VolDescriptor.Unknown.Id,
>                     (VOID *)UDF_NSR3_IDENTIFIER,
>                     sizeof (VolDescriptor.Unknown.Id)) != 0)) {
> -    return EFI_UNSUPPORTED;
> +    return EFI_NOT_FOUND;
>    }
> 
>    //
> @@ -204,7 +202,7 @@ SupportUdfFileSystem (
>    //
>    Offset += UDF_LOGICAL_SECTOR_SIZE;
>    if (Offset >= EndDiskOffset) {
> -    return EFI_UNSUPPORTED;
> +    return EFI_NOT_FOUND;
>    }
> 
>    Status = DiskIo->ReadDisk (
> @@ -221,15 +219,291 @@ SupportUdfFileSystem (
>    if (CompareMem ((VOID *)VolDescriptor.Unknown.Id,
>                    (VOID *)UDF_TEA_IDENTIFIER,
>                    sizeof (VolDescriptor.Unknown.Id)) != 0) {
> -    return EFI_UNSUPPORTED;
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Check if Logical Volume Descriptor is supported by current EDK2 UDF file
> +  system implementation.
> +
> +  @param[in]  LogicalVolDesc  Logical Volume Descriptor pointer.
> +
> +  @retval TRUE                Logical Volume Descriptor is supported.
> +  @retval FALSE               Logical Volume Descriptor is not supported.
> +
> +**/
> +BOOLEAN
> +IsLogicalVolumeDescriptorSupported (
> +  UDF_LOGICAL_VOLUME_DESCRIPTOR *LogicalVolDesc
> +  )
> +{
> +  //
> +  // Check for a valid UDF revision range
> +  //
> +  switch (UDF_LVD_REVISION (LogicalVolDesc)) {
> +  case 0x0102:
> +  case 0x0150:
> +  case 0x0200:
> +  case 0x0201:
> +  case 0x0250:
> +  case 0x0260:
> +    break;
> +  default:
> +    return FALSE;
> +  }
> +
> +  //
> +  // Check for a single Partition Map
> +  //
> +  if (LogicalVolDesc->NumberOfPartitionMaps > 1) {
> +    return FALSE;
> +  }
> +  //
> +  // UDF 1.02 revision supports only Type 1 (Physical) partitions, but
> +  // let's check it any way.
> +  //
> +  // PartitionMap[0] -> type
> +  // PartitionMap[1] -> length (in bytes)
> +  //
> +  if (LogicalVolDesc->PartitionMaps[0] != 1 ||
> +      LogicalVolDesc->PartitionMaps[1] != 6) {
> +    return FALSE;
> +  }
> +
> +  return TRUE;
> +}
> +
> +/**
> +  Find UDF logical volume location and whether it is supported by current EDK2
> +  UDF file system implementation.
> +
> +  @param[in]  BlockIo             BlockIo interface.
> +  @param[in]  DiskIo              DiskIo interface.
> +  @param[in]  AnchorPoint         Anchor volume descriptor pointer.
> +  @param[out] MainVdsStartBlock   Main VDS starting block number.
> +  @param[out] MainVdsEndBlock     Main VDS ending block number.
> +
> +  @retval EFI_SUCCESS             UDF logical volume was found.
> +  @retval EFI_VOLUME_CORRUPTED    UDF file system structures are
> corrupted.
> +  @retval EFI_UNSUPPORTED         UDF logical volume is not supported.
> +  @retval other                   Failed to perform disk I/O.
> +
> +**/
> +EFI_STATUS
> +FindLogicalVolumeLocation (
> +  IN   EFI_BLOCK_IO_PROTOCOL                 *BlockIo,
> +  IN   EFI_DISK_IO_PROTOCOL                  *DiskIo,
> +  IN   UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint,
> +  OUT  UINT64                                *MainVdsStartBlock,
> +  OUT  UINT64                                *MainVdsEndBlock
> +  )
> +{
> +  EFI_STATUS                     Status;
> +  UINT32                         BlockSize;
> +  EFI_LBA                        LastBlock;
> +  UDF_EXTENT_AD                  *ExtentAd;
> +  UINT64                         SeqBlocksNum;
> +  UINT64                         SeqStartBlock;
> +  UINT64                         GuardMainVdsStartBlock;
> +  VOID                           *Buffer;
> +  UINT64                         SeqEndBlock;
> +  BOOLEAN                        StopSequence;
> +  UINTN                          LvdsCount;
> +  UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;
> +  UDF_DESCRIPTOR_TAG             *DescriptorTag;
> +
> +  BlockSize = BlockIo->Media->BlockSize;
> +  LastBlock = BlockIo->Media->LastBlock;
> +  ExtentAd = &AnchorPoint->MainVolumeDescriptorSequenceExtent;
> +
> +  //
> +  // UDF 2.60, 2.2.3.1 struct MainVolumeDescriptorSequenceExtent
> +  //
> +  // The Main Volume Descriptor Sequence Extent shall have a minimum length
> of
> +  // 16 logical sectors.
> +  //
> +  // Also make sure it does not exceed maximum number of blocks in the disk.
> +  //
> +  SeqBlocksNum = DivU64x32 ((UINT64)ExtentAd->ExtentLength, BlockSize);
> +  if (SeqBlocksNum < 16 || (EFI_LBA)SeqBlocksNum > LastBlock + 1) {
> +    return EFI_VOLUME_CORRUPTED;
> +  }
> +
> +  //
> +  // Check for valid Volume Descriptor Sequence starting block number
> +  //
> +  SeqStartBlock = (UINT64)ExtentAd->ExtentLocation;
> +  if (SeqStartBlock > LastBlock ||
> +      SeqStartBlock + SeqBlocksNum - 1 > LastBlock) {
> +    return EFI_VOLUME_CORRUPTED;
>    }
> 
> +  GuardMainVdsStartBlock = SeqStartBlock;
> +
> +  //
> +  // Allocate buffer for reading disk blocks
> +  //
> +  Buffer = AllocateZeroPool ((UINTN)BlockSize);
> +  if (Buffer == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  SeqEndBlock = SeqStartBlock + SeqBlocksNum;
> +  StopSequence = FALSE;
> +  LvdsCount = 0;
> +  Status = EFI_VOLUME_CORRUPTED;
> +  //
> +  // Start Main Volume Descriptor Sequence
> +  //
> +  for (; SeqStartBlock < SeqEndBlock && !StopSequence; SeqStartBlock++) {
> +    //
> +    // Read disk block
> +    //
> +    Status = BlockIo->ReadBlocks (
> +      BlockIo,
> +      BlockIo->Media->MediaId,
> +      SeqStartBlock,
> +      BlockSize,
> +      Buffer
> +      );
> +    if (EFI_ERROR (Status)) {
> +      goto Out_Free;
> +    }
> +
> +    DescriptorTag = Buffer;
> +
> +    //
> +    // ECMA 167, 8.4.1 Contents of a Volume Descriptor Sequence
> +    //
> +    // - A Volume Descriptor Sequence shall contain one or more Primary
> Volume
> +    //   Descriptors.
> +    // - A Volume Descriptor Sequence shall contain zero or more
> Implementation
> +    //   Use Volume Descriptors.
> +    // - A Volume Descriptor Sequence shall contain zero or more Partition
> +    //   Descriptors.
> +    // - A Volume Descriptor Sequence shall contain zero or more Logical
> Volume
> +    //   Descriptors.
> +    // - A Volume Descriptor Sequence shall contain zero or more Unallocated
> +    //   Space Descriptors.
> +    //
> +    switch (UDF_TAG_ID (DescriptorTag)) {
> +    case UdfPrimaryVolumeDescriptor:
> +    case UdfImplemenationUseVolumeDescriptor:
> +    case UdfPartitionDescriptor:
> +    case UdfUnallocatedSpaceDescriptor:
> +      break;
> +
> +    case UdfLogicalVolumeDescriptor:
> +      LogicalVolDesc = Buffer;
> +
> +      //
> +      // Check for existence of a single LVD and whether it is supported by
> +      // current EDK2 UDF file system implementation.
> +      //
> +      if (++LvdsCount > 1 ||
> +          !IsLogicalVolumeDescriptorSupported (LogicalVolDesc)) {
> +        Status = EFI_UNSUPPORTED;
> +        StopSequence = TRUE;
> +      }
> +
> +      break;
> +
> +    case UdfTerminatingDescriptor:
> +      //
> +      // Stop the sequence when we find a Terminating Descriptor
> +      // (aka Unallocated Sector), se we don't have to walk all the unallocated
> +      // area unnecessarily.
> +      //
> +      StopSequence = TRUE;
> +      break;
> +
> +    default:
> +      //
> +      // An invalid Volume Descriptor has been found in the sequece. Volume is
> +      // corrupted.
> +      //
> +      Status = EFI_VOLUME_CORRUPTED;
> +      goto Out_Free;
> +    }
> +  }
> +
> +  //
> +  // Check if LVD was found
> +  //
> +  if (!EFI_ERROR (Status) && LvdsCount == 1) {
> +    *MainVdsStartBlock = GuardMainVdsStartBlock;
> +    //
> +    // We do not need to read either LVD or PD descriptors to know the last
> +    // valid block in the found UDF file system. It's already LastBlock.
> +    //
> +    *MainVdsEndBlock = LastBlock;
> +
> +    Status = EFI_SUCCESS;
> +  }
> +
> +Out_Free:
> +  //
> +  // Free block read buffer
> +  //
> +  FreePool (Buffer);
> +
> +  return Status;
> +}
> +
> +/**
> +  Find a supported UDF file system in block device.
> +
> +  @param[in]  BlockIo             BlockIo interface.
> +  @param[in]  DiskIo              DiskIo interface.
> +  @param[out] StartingLBA         UDF file system starting LBA.
> +  @param[out] EndingLBA           UDF file system starting LBA.
> +
> +  @retval EFI_SUCCESS             UDF file system was found.
> +  @retval other                   UDF file system was not found.
> +
> +**/
> +EFI_STATUS
> +FindUdfFileSystem (
> +  IN EFI_BLOCK_IO_PROTOCOL  *BlockIo,
> +  IN EFI_DISK_IO_PROTOCOL   *DiskIo,
> +  OUT EFI_LBA               *StartingLBA,
> +  OUT EFI_LBA               *EndingLBA
> +  )
> +{
> +  EFI_STATUS Status;
> +  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  AnchorPoint;
> +
> +  //
> +  // Find UDF volume identifiers
> +  //
> +  Status = FindUdfVolumeIdentifiers (BlockIo, DiskIo);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Find Anchor Volume Descriptor Pointer
> +  //
>    Status = FindAnchorVolumeDescriptorPointer (BlockIo, DiskIo, &AnchorPoint);
>    if (EFI_ERROR (Status)) {
> -    return EFI_UNSUPPORTED;
> +    return Status;
>    }
> 
> -  return EFI_SUCCESS;
> +  //
> +  // Find Logical Volume location
> +  //
> +  Status = FindLogicalVolumeLocation (
> +    BlockIo,
> +    DiskIo,
> +    &AnchorPoint,
> +    (UINT64 *)StartingLBA,
> +    (UINT64 *)EndingLBA
> +    );
> +
> +  return Status;
>  }
> 
>  /**
> @@ -263,9 +537,9 @@ PartitionInstallUdfChildHandles (
>    UINT32                       RemainderByMediaBlockSize;
>    EFI_STATUS                   Status;
>    EFI_BLOCK_IO_MEDIA           *Media;
> -  EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode;
> -  EFI_GUID                     *VendorDefinedGuid;
>    EFI_PARTITION_INFO_PROTOCOL  PartitionInfo;
> +  EFI_LBA                      StartingLBA;
> +  EFI_LBA                      EndingLBA;
> 
>    Media = BlockIo->Media;
> 
> @@ -281,35 +555,10 @@ PartitionInstallUdfChildHandles (
>      return EFI_NOT_FOUND;
>    }
> 
> -  DevicePathNode = DevicePath;
> -  while (!IsDevicePathEnd (DevicePathNode)) {
> -    //
> -    // Do not allow checking for UDF file systems in CDROM "El Torito"
> -    // partitions, and skip duplicate installation of UDF file system child
> -    // nodes.
> -    //
> -    if (DevicePathType (DevicePathNode) == MEDIA_DEVICE_PATH) {
> -      if (DevicePathSubType (DevicePathNode) == MEDIA_CDROM_DP) {
> -        return EFI_NOT_FOUND;
> -      }
> -      if (DevicePathSubType (DevicePathNode) == MEDIA_VENDOR_DP) {
> -        VendorDefinedGuid = (EFI_GUID *)((UINTN)DevicePathNode +
> -                                         OFFSET_OF (VENDOR_DEVICE_PATH, Guid));
> -        if (CompareGuid (VendorDefinedGuid, &gUdfDevPathGuid)) {
> -          return EFI_NOT_FOUND;
> -        }
> -      }
> -    }
> -    //
> -    // Try next device path node
> -    //
> -    DevicePathNode = NextDevicePathNode (DevicePathNode);
> -  }
> -
>    //
> -  // Check if block device supports an UDF file system
> +  // Search for an UDF file system on block device
>    //
> -  Status = SupportUdfFileSystem (BlockIo, DiskIo);
> +  Status = FindUdfFileSystem (BlockIo, DiskIo, &StartingLBA, &EndingLBA);
>    if (EFI_ERROR (Status)) {
>      return EFI_NOT_FOUND;
>    }
> @@ -334,8 +583,8 @@ PartitionInstallUdfChildHandles (
>      DevicePath,
>      (EFI_DEVICE_PATH_PROTOCOL *)&gUdfDevicePath,
>      &PartitionInfo,
> -    0,
> -    Media->LastBlock,
> +    StartingLBA,
> +    EndingLBA,
>      Media->BlockSize
>      );
>    if (!EFI_ERROR (Status)) {
> diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/File.c
> b/MdeModulePkg/Universal/Disk/UdfDxe/File.c
> index 625f2c5637..6f07bf2066 100644
> --- a/MdeModulePkg/Universal/Disk/UdfDxe/File.c
> +++ b/MdeModulePkg/Universal/Disk/UdfDxe/File.c
> @@ -131,7 +131,6 @@ Error_Alloc_Priv_File_Data:
>    CleanupFileInformation (&PrivFsData->Root);
> 
>  Error_Find_Root_Dir:
> -  CleanupVolumeInformation (&PrivFsData->Volume);
> 
>  Error_Read_Udf_Volume:
>  Error_Invalid_Params:
> @@ -429,7 +428,7 @@ UdfRead (
>      }
>      ASSERT (NewFileEntryData != NULL);
> 
> -    if (IS_FE_SYMLINK (NewFileEntryData)) {
> +    if (FE_ICB_FILE_TYPE (NewFileEntryData) == UdfFileEntrySymlink) {
>        Status = ResolveSymlink (
>          BlockIo,
>          DiskIo,
> @@ -529,7 +528,6 @@ UdfClose (
>    EFI_TPL                     OldTpl;
>    EFI_STATUS                  Status;
>    PRIVATE_UDF_FILE_DATA       *PrivFileData;
> -  PRIVATE_UDF_SIMPLE_FS_DATA  *PrivFsData;
> 
>    OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
> 
> @@ -542,8 +540,6 @@ UdfClose (
> 
>    PrivFileData = PRIVATE_UDF_FILE_DATA_FROM_THIS (This);
> 
> -  PrivFsData = PRIVATE_UDF_SIMPLE_FS_DATA_FROM_THIS (PrivFileData-
> >SimpleFs);
> -
>    if (!PrivFileData->IsRootDirectory) {
>      CleanupFileInformation (&PrivFileData->File);
> 
> @@ -552,10 +548,6 @@ UdfClose (
>      }
>    }
> 
> -  if (--PrivFsData->OpenFiles == 0) {
> -    CleanupVolumeInformation (&PrivFsData->Volume);
> -  }
> -
>    FreePool ((VOID *)PrivFileData);
> 
>  Exit:
> @@ -652,7 +644,7 @@ UdfGetPosition (
>    // As per UEFI spec, if the file handle is a directory, then the current file
>    // position has no meaning and the operation is not supported.
>    //
> -  if (IS_FID_DIRECTORY_FILE (&PrivFileData->File.FileIdentifierDesc)) {
> +  if (IS_FID_DIRECTORY_FILE (PrivFileData->File.FileIdentifierDesc)) {
>      return  EFI_UNSUPPORTED;
>    }
> 
> @@ -788,7 +780,7 @@ UdfGetInfo (
>    } else if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {
>      String = VolumeLabel;
> 
> -    FileSetDesc = PrivFsData->Volume.FileSetDescs[0];
> +    FileSetDesc = &PrivFsData->Volume.FileSetDesc;
> 
>      OstaCompressed = &FileSetDesc->LogicalVolumeIdentifier[0];
> 
> @@ -847,7 +839,7 @@ UdfGetInfo (
>      FileSystemInfo->Size        = FileSystemInfoLength;
>      FileSystemInfo->ReadOnly    = TRUE;
>      FileSystemInfo->BlockSize   =
> -      LV_BLOCK_SIZE (&PrivFsData->Volume, UDF_DEFAULT_LV_NUM);
> +      PrivFsData->Volume.LogicalVolDesc.LogicalBlockSize;
>      FileSystemInfo->VolumeSize  = VolumeSize;
>      FileSystemInfo->FreeSpace   = FreeSpaceSize;
> 
> diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
> b/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
> index 5df267761f..62d817989f 100644
> --- a/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
> +++ b/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
> @@ -38,11 +38,12 @@ FindAnchorVolumeDescriptorPointer (
>    OUT  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint
>    )
>  {
> -  EFI_STATUS  Status;
> -  UINT32      BlockSize;
> -  EFI_LBA     EndLBA;
> -  EFI_LBA     DescriptorLBAs[4];
> -  UINTN       Index;
> +  EFI_STATUS          Status;
> +  UINT32              BlockSize;
> +  EFI_LBA             EndLBA;
> +  EFI_LBA             DescriptorLBAs[4];
> +  UINTN               Index;
> +  UDF_DESCRIPTOR_TAG  *DescriptorTag;
> 
>    BlockSize = BlockIo->Media->BlockSize;
>    EndLBA = BlockIo->Media->LastBlock;
> @@ -62,10 +63,13 @@ FindAnchorVolumeDescriptorPointer (
>      if (EFI_ERROR (Status)) {
>        return Status;
>      }
> +
> +    DescriptorTag = &AnchorPoint->DescriptorTag;
> +
>      //
>      // Check if read LBA has a valid AVDP descriptor.
>      //
> -    if (IS_AVDP (AnchorPoint)) {
> +    if (DescriptorTag->TagIdentifier == UdfAnchorVolumeDescriptorPointer) {
>        return EFI_SUCCESS;
>      }
>    }
> @@ -99,148 +103,98 @@ StartMainVolumeDescriptorSequence (
>    OUT  UDF_VOLUME_INFO                       *Volume
>    )
>  {
> -  EFI_STATUS                     Status;
> -  UINT32                         BlockSize;
> -  UDF_EXTENT_AD                  *ExtentAd;
> -  UINT64                         StartingLsn;
> -  UINT64                         EndingLsn;
> -  VOID                           *Buffer;
> -  UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;
> -  UDF_PARTITION_DESCRIPTOR       *PartitionDesc;
> -  UINTN                          Index;
> -  UINT32                         LogicalBlockSize;
> +  EFI_STATUS            Status;
> +  UINT32                BlockSize;
> +  UDF_EXTENT_AD         *ExtentAd;
> +  EFI_LBA               SeqStartBlock;
> +  EFI_LBA               SeqEndBlock;
> +  BOOLEAN               StopSequence;
> +  VOID                  *Buffer;
> +  UDF_DESCRIPTOR_TAG    *DescriptorTag;
> +  UINT32                LogicalBlockSize;
> +
> +  BlockSize = BlockIo->Media->BlockSize;
> +  ExtentAd = &AnchorPoint->MainVolumeDescriptorSequenceExtent;
> 
>    //
> -  // We've already found an ADVP on the volume. It contains the extent
> -  // (MainVolumeDescriptorSequenceExtent) where the Main Volume
> Descriptor
> -  // Sequence starts. Therefore, we'll look for Logical Volume Descriptors and
> -  // Partitions Descriptors and save them in memory, accordingly.
> -  //
> -  // Note also that each descriptor will be aligned on a block size (BlockSize)
> -  // boundary, so we need to read one block at a time.
> +  // Allocate buffer for reading disk blocks
>    //
> -  BlockSize    = BlockIo->Media->BlockSize;
> -  ExtentAd     = &AnchorPoint->MainVolumeDescriptorSequenceExtent;
> -  StartingLsn  = (UINT64)ExtentAd->ExtentLocation;
> -  EndingLsn    = StartingLsn + DivU64x32 (
> -                                     (UINT64)ExtentAd->ExtentLength,
> -                                     BlockSize
> -                                     );
> -
> -  Volume->LogicalVolDescs =
> -    (UDF_LOGICAL_VOLUME_DESCRIPTOR **)AllocateZeroPool (ExtentAd-
> >ExtentLength);
> -  if (Volume->LogicalVolDescs == NULL) {
> -    return EFI_OUT_OF_RESOURCES;
> -  }
> -
> -  Volume->PartitionDescs =
> -    (UDF_PARTITION_DESCRIPTOR **)AllocateZeroPool (ExtentAd-
> >ExtentLength);
> -  if (Volume->PartitionDescs == NULL) {
> -    Status = EFI_OUT_OF_RESOURCES;
> -    goto Error_Alloc_Pds;
> -  }
> -
> -  Buffer = AllocateZeroPool (BlockSize);
> +  Buffer = AllocateZeroPool ((UINTN)BlockSize);
>    if (Buffer == NULL) {
> -    Status = EFI_OUT_OF_RESOURCES;
> -    goto Error_Alloc_Buf;
> +    return EFI_OUT_OF_RESOURCES;
>    }
> 
> -  Volume->LogicalVolDescsNo  = 0;
> -  Volume->PartitionDescsNo   = 0;
> -
> -  while (StartingLsn <= EndingLsn) {
> -    Status = DiskIo->ReadDisk (
> -      DiskIo,
> +  //
> +  // The logical partition created by Partition driver is relative to the main
> +  // VDS extent location, so we start the Main Volume Descriptor Sequence at
> +  // LBA 0.
> +  //
> +  // We don't need to check again if we have valid Volume Descriptors here
> since
> +  // Partition driver already did.
> +  //
> +  SeqStartBlock = 0;
> +  SeqEndBlock = SeqStartBlock + DivU64x32 ((UINT64)ExtentAd->ExtentLength,
> +                                           BlockSize);
> +  StopSequence = FALSE;
> +  for (; SeqStartBlock < SeqEndBlock && !StopSequence; SeqStartBlock++) {
> +    //
> +    // Read disk block
> +    //
> +    Status = BlockIo->ReadBlocks (
> +      BlockIo,
>        BlockIo->Media->MediaId,
> -      MultU64x32 (StartingLsn, BlockSize),
> +      SeqStartBlock,
>        BlockSize,
>        Buffer
>        );
>      if (EFI_ERROR (Status)) {
> -      goto Error_Read_Disk_Blk;
> +      goto Out_Free;
>      }
> 
> -    if (IS_TD (Buffer)) {
> +    DescriptorTag = Buffer;
> +
> +    switch (UDF_TAG_ID (DescriptorTag)) {
> +    case UdfPartitionDescriptor:
>        //
> -      // Found a Terminating Descriptor. Stop the sequence then.
> +      // Save Partition Descriptor
>        //
> +      CopyMem (&Volume->PartitionDesc, Buffer, sizeof (Volume-
> >PartitionDesc));
>        break;
> -    }
> 
> -    if (IS_LVD (Buffer)) {
> +    case UdfLogicalVolumeDescriptor:
>        //
> -      // Found a Logical Volume Descriptor.
> +      // Save Logical Volume Descriptor
>        //
> -      LogicalVolDesc =
> -        (UDF_LOGICAL_VOLUME_DESCRIPTOR *)
> -        AllocateZeroPool (sizeof (UDF_LOGICAL_VOLUME_DESCRIPTOR));
> -      if (LogicalVolDesc == NULL) {
> -        Status = EFI_OUT_OF_RESOURCES;
> -        goto Error_Alloc_Lvd;
> -      }
> +      CopyMem (&Volume->LogicalVolDesc, Buffer, sizeof (Volume-
> >LogicalVolDesc));
> +      break;
> 
> -      CopyMem ((VOID *)LogicalVolDesc, Buffer,
> -               sizeof (UDF_LOGICAL_VOLUME_DESCRIPTOR));
> -      Volume->LogicalVolDescs[Volume->LogicalVolDescsNo++] =
> LogicalVolDesc;
> -    } else if (IS_PD (Buffer)) {
> -      //
> -      // Found a Partition Descriptor.
> -      //
> -      PartitionDesc =
> -        (UDF_PARTITION_DESCRIPTOR *)
> -        AllocateZeroPool (sizeof (UDF_PARTITION_DESCRIPTOR));
> -      if (PartitionDesc == NULL) {
> -        Status = EFI_OUT_OF_RESOURCES;
> -        goto Error_Alloc_Pd;
> -      }
> +    case UdfTerminatingDescriptor:
> +      StopSequence = TRUE;
> +      break;
> 
> -      CopyMem ((VOID *)PartitionDesc, Buffer,
> -               sizeof (UDF_PARTITION_DESCRIPTOR));
> -      Volume->PartitionDescs[Volume->PartitionDescsNo++] = PartitionDesc;
> +    default:
> +      ;
>      }
> -
> -    StartingLsn++;
>    }
> 
>    //
> -  // When an UDF volume (revision 2.00 or higher) contains a File Entry rather
> -  // than an Extended File Entry (which is not recommended as per spec), we
> need
> -  // to make sure the size of a FE will be _at least_ 2048
> -  // (UDF_LOGICAL_SECTOR_SIZE) bytes long to keep backward compatibility.
> +  // Determine FE (File Entry) size
>    //
> -  LogicalBlockSize = LV_BLOCK_SIZE (Volume, UDF_DEFAULT_LV_NUM);
> +  LogicalBlockSize = Volume->LogicalVolDesc.LogicalBlockSize;
>    if (LogicalBlockSize >= UDF_LOGICAL_SECTOR_SIZE) {
> -    Volume->FileEntrySize = LogicalBlockSize;
> +    Volume->FileEntrySize = (UINTN)LogicalBlockSize;
>    } else {
>      Volume->FileEntrySize = UDF_LOGICAL_SECTOR_SIZE;
>    }
> 
> -  FreePool (Buffer);
> +  Status = EFI_SUCCESS;
> 
> -  return EFI_SUCCESS;
> -
> -Error_Alloc_Pd:
> -Error_Alloc_Lvd:
> -  for (Index = 0; Index < Volume->PartitionDescsNo; Index++) {
> -    FreePool ((VOID *)Volume->PartitionDescs[Index]);
> -  }
> -
> -  for (Index = 0; Index < Volume->LogicalVolDescsNo; Index++) {
> -    FreePool ((VOID *)Volume->LogicalVolDescs[Index]);
> -  }
> -
> -Error_Read_Disk_Blk:
> +Out_Free:
> +  //
> +  // Free block read buffer
> +  //
>    FreePool (Buffer);
> 
> -Error_Alloc_Buf:
> -  FreePool ((VOID *)Volume->PartitionDescs);
> -  Volume->PartitionDescs = NULL;
> -
> -Error_Alloc_Pds:
> -  FreePool ((VOID *)Volume->LogicalVolDescs);
> -  Volume->LogicalVolDescs = NULL;
> -
>    return Status;
>  }
> 
> @@ -262,48 +216,53 @@ GetPdFromLongAd (
>    )
>  {
>    UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;
> -  UINTN                          Index;
> -  UDF_PARTITION_DESCRIPTOR       *PartitionDesc;
>    UINT16                         PartitionNum;
> 
> -  LogicalVolDesc = Volume->LogicalVolDescs[UDF_DEFAULT_LV_NUM];
> +  LogicalVolDesc = &Volume->LogicalVolDesc;
> 
> -  switch (LV_UDF_REVISION (LogicalVolDesc)) {
> +  switch (UDF_LVD_REVISION (LogicalVolDesc)) {
>    case 0x0102:
> +  case 0x0150:
> +  case 0x0200:
> +  case 0x0201:
> +  case 0x0250:
> +  case 0x0260:
>      //
> -    // As per UDF 1.02 specification:
> +    // UDF 1.02 specification:
>      //
>      // There shall be exactly one prevailing Logical Volume Descriptor recorded
>      // per Volume Set. The Partition Maps field shall contain only Type 1
>      // Partition Maps.
>      //
> -    PartitionNum = *(UINT16 *)((UINTN)&LogicalVolDesc->PartitionMaps[4]);
> -    break;
> -  case 0x0150:
> +    // UDF 1.50 through 2.60 specs say:
>      //
> -    // Ensure Type 1 Partition map. Other types aren't supported in this
> -    // implementation.
> +    // For the purpose of interchange partition maps shall be limited to
> +    // Partition Map type 1, except type 2 maps as described in the document.
> +    //
> +    // NOTE: Only one Type 1 (Physical) Partition is supported. It has been
> +    // checked already in Partition driver for existence of a single Type 1
> +    // Partition map, so we don't have to double check here.
> +    //
> +    // Partition reference number can also be retrieved from
> +    // LongAd->ExtentLocation.PartitionReferenceNumber, however the spec
> says
> +    // it may be 0, so let's not rely on it.
>      //
> -    if (LogicalVolDesc->PartitionMaps[0] != 1 ||
> -        LogicalVolDesc->PartitionMaps[1] != 6) {
> -      return NULL;
> -    }
>      PartitionNum = *(UINT16 *)((UINTN)&LogicalVolDesc->PartitionMaps[4]);
>      break;
> -  case 0x0260:
> +
> +  default:
>      //
> -    // Fall through.
> +    // Unsupported UDF revision
>      //
> -  default:
> -    PartitionNum = LongAd->ExtentLocation.PartitionReferenceNumber;
> -    break;
> +    return NULL;
>    }
> 
> -  for (Index = 0; Index < Volume->PartitionDescsNo; Index++) {
> -    PartitionDesc = Volume->PartitionDescs[Index];
> -    if (PartitionDesc->PartitionNumber == PartitionNum) {
> -      return PartitionDesc;
> -    }
> +  //
> +  // Check if partition number matches Partition Descriptor found in Main
> Volume
> +  // Descriptor Sequence.
> +  //
> +  if (Volume->PartitionDesc.PartitionNumber == PartitionNum) {
> +    return &Volume->PartitionDesc;
>    }
> 
>    return NULL;
> @@ -329,13 +288,15 @@ GetLongAdLsn (
>    PartitionDesc = GetPdFromLongAd (Volume, LongAd);
>    ASSERT (PartitionDesc != NULL);
> 
> -  return (UINT64)PartitionDesc->PartitionStartingLocation +
> -                 LongAd->ExtentLocation.LogicalBlockNumber;
> +  return (UINT64)PartitionDesc->PartitionStartingLocation -
> +    Volume->MainVdsStartLocation +
> +    LongAd->ExtentLocation.LogicalBlockNumber;
>  }
> 
>  /**
>    Return logical sector number of a given Short Allocation Descriptor.
> 
> +  @param[in]  Volume              Volume pointer.
>    @param[in]  PartitionDesc       Partition Descriptor pointer.
>    @param[in]  ShortAd             Short Allocation Descriptor pointer.
> 
> @@ -344,14 +305,13 @@ GetLongAdLsn (
>  **/
>  UINT64
>  GetShortAdLsn (
> +  IN UDF_VOLUME_INFO                  *Volume,
>    IN UDF_PARTITION_DESCRIPTOR         *PartitionDesc,
>    IN UDF_SHORT_ALLOCATION_DESCRIPTOR  *ShortAd
>    )
>  {
> -  ASSERT (PartitionDesc != NULL);
> -
> -  return (UINT64)PartitionDesc->PartitionStartingLocation +
> -    ShortAd->ExtentPosition;
> +  return (UINT64)PartitionDesc->PartitionStartingLocation -
> +    Volume->MainVdsStartLocation + ShortAd->ExtentPosition;
>  }
> 
>  /**
> @@ -363,8 +323,6 @@ GetShortAdLsn (
>    @param[in]  BlockIo             BlockIo interface.
>    @param[in]  DiskIo              DiskIo interface.
>    @param[in]  Volume              Volume information pointer.
> -  @param[in]  LogicalVolDescNum   Index of Logical Volume Descriptor
> -  @param[out] FileSetDesc         File Set Descriptor pointer.
> 
>    @retval EFI_SUCCESS             File Set Descriptor pointer found.
>    @retval EFI_VOLUME_CORRUPTED    The file system structures are corrupted.
> @@ -375,36 +333,42 @@ EFI_STATUS
>  FindFileSetDescriptor (
>    IN   EFI_BLOCK_IO_PROTOCOL    *BlockIo,
>    IN   EFI_DISK_IO_PROTOCOL     *DiskIo,
> -  IN   UDF_VOLUME_INFO          *Volume,
> -  IN   UINTN                    LogicalVolDescNum,
> -  OUT  UDF_FILE_SET_DESCRIPTOR  *FileSetDesc
> +  IN   UDF_VOLUME_INFO          *Volume
>    )
>  {
>    EFI_STATUS                     Status;
>    UINT64                         Lsn;
>    UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;
> +  UDF_DESCRIPTOR_TAG             *DescriptorTag;
> 
> -  LogicalVolDesc = Volume->LogicalVolDescs[LogicalVolDescNum];
> +  LogicalVolDesc = &Volume->LogicalVolDesc;
>    Lsn = GetLongAdLsn (Volume, &LogicalVolDesc->LogicalVolumeContentsUse);
> 
>    //
> -  // Read extent (Long Ad).
> +  // As per UDF 2.60 specification:
> +  //
> +  // There shall be exactly one File Set Descriptor recorded per Logical
> +  // Volume.
> +  //
> +  // Read disk block
>    //
>    Status = DiskIo->ReadDisk (
>      DiskIo,
>      BlockIo->Media->MediaId,
>      MultU64x32 (Lsn, LogicalVolDesc->LogicalBlockSize),
> -    sizeof (UDF_FILE_SET_DESCRIPTOR),
> -    (VOID *)FileSetDesc
> +    sizeof (Volume->FileSetDesc),
> +    &Volume->FileSetDesc
>      );
>    if (EFI_ERROR (Status)) {
>      return Status;
>    }
> 
> +  DescriptorTag = &Volume->FileSetDesc.DescriptorTag;
> +
>    //
> -  // Check if the read extent contains a valid FSD's tag identifier.
> +  // Check if read block is a File Set Descriptor
>    //
> -  if (!IS_FSD (FileSetDesc)) {
> +  if (UDF_TAG_ID (DescriptorTag) != UdfFileSetDescriptor) {
>      return EFI_VOLUME_CORRUPTED;
>    }
> 
> @@ -412,82 +376,6 @@ FindFileSetDescriptor (
>  }
> 
>  /**
> -  Get all File Set Descriptors for each Logical Volume Descriptor.
> -
> -  @param[in]      BlockIo         BlockIo interface.
> -  @param[in]      DiskIo          DiskIo interface.
> -  @param[in, out] Volume          Volume information pointer.
> -
> -  @retval EFI_SUCCESS             File Set Descriptors were got.
> -  @retval EFI_OUT_OF_RESOURCES    File Set Descriptors were not got due to
> lack
> -                                  of resources.
> -  @retval other                   Error occured when finding File Set
> -                                  Descriptor in Logical Volume Descriptor.
> -
> -**/
> -EFI_STATUS
> -GetFileSetDescriptors (
> -  IN      EFI_BLOCK_IO_PROTOCOL  *BlockIo,
> -  IN      EFI_DISK_IO_PROTOCOL   *DiskIo,
> -  IN OUT  UDF_VOLUME_INFO        *Volume
> -  )
> -{
> -  EFI_STATUS               Status;
> -  UINTN                    Index;
> -  UDF_FILE_SET_DESCRIPTOR  *FileSetDesc;
> -  UINTN                    Count;
> -
> -  Volume->FileSetDescs =
> -    (UDF_FILE_SET_DESCRIPTOR **)AllocateZeroPool (
> -      Volume->LogicalVolDescsNo * sizeof (UDF_FILE_SET_DESCRIPTOR));
> -  if (Volume->FileSetDescs == NULL) {
> -    return EFI_OUT_OF_RESOURCES;
> -  }
> -
> -  for (Index = 0; Index < Volume->LogicalVolDescsNo; Index++) {
> -    FileSetDesc = AllocateZeroPool (sizeof (UDF_FILE_SET_DESCRIPTOR));
> -    if (FileSetDesc == NULL) {
> -      Status = EFI_OUT_OF_RESOURCES;
> -      goto Error_Alloc_Fsd;
> -    }
> -
> -    //
> -    // Find a FSD for this LVD.
> -    //
> -    Status = FindFileSetDescriptor (
> -      BlockIo,
> -      DiskIo,
> -      Volume,
> -      Index,
> -      FileSetDesc
> -      );
> -    if (EFI_ERROR (Status)) {
> -      goto Error_Find_Fsd;
> -    }
> -
> -    //
> -    // Got one. Save it.
> -    //
> -    Volume->FileSetDescs[Index] = FileSetDesc;
> -  }
> -
> -  Volume->FileSetDescsNo = Volume->LogicalVolDescsNo;
> -  return EFI_SUCCESS;
> -
> -Error_Find_Fsd:
> -  Count = Index + 1;
> -  for (Index = 0; Index < Count; Index++) {
> -    FreePool ((VOID *)Volume->FileSetDescs[Index]);
> -  }
> -
> -  FreePool ((VOID *)Volume->FileSetDescs);
> -  Volume->FileSetDescs = NULL;
> -
> -Error_Alloc_Fsd:
> -  return Status;
> -}
> -
> -/**
>    Read Volume and File Structure on an UDF file system.
> 
>    @param[in]   BlockIo            BlockIo interface.
> @@ -507,9 +395,10 @@ ReadVolumeFileStructure (
>  {
>    EFI_STATUS                            Status;
>    UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  AnchorPoint;
> +  UDF_EXTENT_AD                         *ExtentAd;
> 
>    //
> -  // Find an AVDP.
> +  // Find Anchor Volume Descriptor Pointer
>    //
>    Status = FindAnchorVolumeDescriptorPointer (
>      BlockIo,
> @@ -521,7 +410,14 @@ ReadVolumeFileStructure (
>    }
> 
>    //
> -  // AVDP has been found. Start MVDS.
> +  // Save Main VDS start block number
> +  //
> +  ExtentAd = &AnchorPoint.MainVolumeDescriptorSequenceExtent;
> +
> +  Volume->MainVdsStartLocation = (UINT64)ExtentAd->ExtentLocation;
> +
> +  //
> +  // Start Main Volume Descriptor Sequence.
>    //
>    Status = StartMainVolumeDescriptorSequence (
>      BlockIo,
> @@ -620,16 +516,19 @@ GetFileEntryData (
>    OUT  UINT64  *Length
>    )
>  {
> +  UDF_DESCRIPTOR_TAG       *DescriptorTag;
>    UDF_EXTENDED_FILE_ENTRY  *ExtendedFileEntry;
>    UDF_FILE_ENTRY           *FileEntry;
> 
> -  if (IS_EFE (FileEntryData)) {
> +  DescriptorTag = FileEntryData;
> +
> +  if (UDF_TAG_ID (DescriptorTag) == UdfExtendedFileEntry) {
>      ExtendedFileEntry = (UDF_EXTENDED_FILE_ENTRY *)FileEntryData;
> 
>      *Length  = ExtendedFileEntry->InformationLength;
>      *Data    = (VOID *)((UINT8 *)ExtendedFileEntry->Data +
>                          ExtendedFileEntry->LengthOfExtendedAttributes);
> -  } else if (IS_FE (FileEntryData)) {
> +  } else if (UDF_TAG_ID (DescriptorTag) == UdfFileEntry) {
>      FileEntry = (UDF_FILE_ENTRY *)FileEntryData;
> 
>      *Length  = FileEntry->InformationLength;
> @@ -654,16 +553,19 @@ GetAdsInformation (
>    OUT  UINT64  *Length
>    )
>  {
> +  UDF_DESCRIPTOR_TAG       *DescriptorTag;
>    UDF_EXTENDED_FILE_ENTRY  *ExtendedFileEntry;
>    UDF_FILE_ENTRY           *FileEntry;
> 
> -  if (IS_EFE (FileEntryData)) {
> +  DescriptorTag = FileEntryData;
> +
> +  if (UDF_TAG_ID (DescriptorTag) == UdfExtendedFileEntry) {
>      ExtendedFileEntry = (UDF_EXTENDED_FILE_ENTRY *)FileEntryData;
> 
>      *Length = ExtendedFileEntry->LengthOfAllocationDescriptors;
>      *AdsData = (VOID *)((UINT8 *)ExtendedFileEntry->Data +
>                          ExtendedFileEntry->LengthOfExtendedAttributes);
> -  } else if (IS_FE (FileEntryData)) {
> +  } else if (UDF_TAG_ID (DescriptorTag) == UdfFileEntry) {
>      FileEntry = (UDF_FILE_ENTRY *)FileEntryData;
> 
>      *Length = FileEntry->LengthOfAllocationDescriptors;
> @@ -850,6 +752,7 @@ GetAllocationDescriptorLsn (
>      return GetLongAdLsn (Volume, (UDF_LONG_ALLOCATION_DESCRIPTOR
> *)Ad);
>    } else if (RecordingFlags == ShortAdsSequence) {
>      return GetShortAdLsn (
> +      Volume,
>        GetPdFromLongAd (Volume, ParentIcb),
>        (UDF_SHORT_ALLOCATION_DESCRIPTOR *)Ad
>        );
> @@ -897,6 +800,7 @@ GetAedAdsOffset (
>    VOID                              *Data;
>    UINT32                            LogicalBlockSize;
>    UDF_ALLOCATION_EXTENT_DESCRIPTOR  *AllocExtDesc;
> +  UDF_DESCRIPTOR_TAG                *DescriptorTag;
> 
>    ExtentLength  = GET_EXTENT_LENGTH (RecordingFlags, Ad);
>    Lsn           = GetAllocationDescriptorLsn (RecordingFlags,
> @@ -909,7 +813,7 @@ GetAedAdsOffset (
>      return EFI_OUT_OF_RESOURCES;
>    }
> 
> -  LogicalBlockSize = LV_BLOCK_SIZE (Volume, UDF_DEFAULT_LV_NUM);
> +  LogicalBlockSize = Volume->LogicalVolDesc.LogicalBlockSize;
> 
>    //
>    // Read extent.
> @@ -925,11 +829,14 @@ GetAedAdsOffset (
>      goto Exit;
>    }
> 
> +  AllocExtDesc = (UDF_ALLOCATION_EXTENT_DESCRIPTOR *)Data;
> +
> +  DescriptorTag = &AllocExtDesc->DescriptorTag;
> +
>    //
>    // Check if read extent contains a valid tag identifier for AED.
>    //
> -  AllocExtDesc = (UDF_ALLOCATION_EXTENT_DESCRIPTOR *)Data;
> -  if (!IS_AED (AllocExtDesc)) {
> +  if (UDF_TAG_ID (DescriptorTag) != UdfAllocationExtentDescriptor) {
>      Status = EFI_VOLUME_CORRUPTED;
>      goto Exit;
>    }
> @@ -1102,7 +1009,7 @@ ReadFile (
>    UINT32                  ExtentLength;
>    UDF_FE_RECORDING_FLAGS  RecordingFlags;
> 
> -  LogicalBlockSize  = LV_BLOCK_SIZE (Volume, UDF_DEFAULT_LV_NUM);
> +  LogicalBlockSize  = Volume->LogicalVolDesc.LogicalBlockSize;
>    DoFreeAed         = FALSE;
> 
>    //
> @@ -1444,7 +1351,7 @@ InternalFindFile (
>    //
>    // Check if parent file is really directory.
>    //
> -  if (!IS_FE_DIRECTORY (Parent->FileEntry)) {
> +  if (FE_ICB_FILE_TYPE (Parent->FileEntry) != UdfFileEntryDirectory) {
>      return EFI_NOT_FOUND;
>    }
> 
> @@ -1489,7 +1396,7 @@ InternalFindFile (
>        break;
>      }
> 
> -    if (IS_FID_PARENT_FILE (FileIdentifierDesc)) {
> +    if (FileIdentifierDesc->FileCharacteristics & PARENT_FILE) {
>        //
>        // This FID contains the location (FE/EFE) of the parent directory of this
>        // directory (Parent), and if FileName is either ".." or "\\", then it's
> @@ -1592,6 +1499,9 @@ ReadUdfVolumeInformation (
>  {
>    EFI_STATUS Status;
> 
> +  //
> +  // Read all necessary UDF volume information and keep it private to the
> driver
> +  //
>    Status = ReadVolumeFileStructure (
>      BlockIo,
>      DiskIo,
> @@ -1601,13 +1511,12 @@ ReadUdfVolumeInformation (
>      return Status;
>    }
> 
> -  Status = GetFileSetDescriptors (
> -    BlockIo,
> -    DiskIo,
> -    Volume
> -    );
> +  //
> +  // Find File Set Descriptor
> +  //
> +  Status = FindFileSetDescriptor (BlockIo, DiskIo, Volume);
>    if (EFI_ERROR (Status)) {
> -    CleanupVolumeInformation (Volume);
> +    return Status;
>    }
> 
>    return Status;
> @@ -1644,7 +1553,7 @@ FindRootDirectory (
>      BlockIo,
>      DiskIo,
>      Volume,
> -    &Volume->FileSetDescs[0]->RootDirectoryIcb,
> +    &Volume->FileSetDesc.RootDirectoryIcb,
>      &File->FileEntry
>      );
>    if (EFI_ERROR (Status)) {
> @@ -1661,7 +1570,7 @@ FindRootDirectory (
>      L"\\",
>      NULL,
>      &Parent,
> -    &Volume->FileSetDescs[0]->RootDirectoryIcb,
> +    &Volume->FileSetDesc.RootDirectoryIcb,
>      File
>      );
>    if (EFI_ERROR (Status)) {
> @@ -1697,12 +1606,13 @@ FindFileEntry (
>    OUT  VOID                            **FileEntry
>    )
>  {
> -  EFI_STATUS  Status;
> -  UINT64      Lsn;
> -  UINT32      LogicalBlockSize;
> +  EFI_STATUS          Status;
> +  UINT64              Lsn;
> +  UINT32              LogicalBlockSize;
> +  UDF_DESCRIPTOR_TAG  *DescriptorTag;
> 
>    Lsn               = GetLongAdLsn (Volume, Icb);
> -  LogicalBlockSize  = LV_BLOCK_SIZE (Volume, UDF_DEFAULT_LV_NUM);
> +  LogicalBlockSize  = Volume->LogicalVolDesc.LogicalBlockSize;
> 
>    *FileEntry = AllocateZeroPool (Volume->FileEntrySize);
>    if (*FileEntry == NULL) {
> @@ -1723,11 +1633,14 @@ FindFileEntry (
>      goto Error_Read_Disk_Blk;
>    }
> 
> +  DescriptorTag = *FileEntry;
> +
>    //
>    // Check if the read extent contains a valid Tag Identifier for the expected
>    // FE/EFE.
>    //
> -  if (!IS_FE (*FileEntry) && !IS_EFE (*FileEntry)) {
> +  if (UDF_TAG_ID (DescriptorTag) != UdfFileEntry &&
> +      UDF_TAG_ID (DescriptorTag) != UdfExtendedFileEntry) {
>      Status = EFI_VOLUME_CORRUPTED;
>      goto Error_Invalid_Fe;
>    }
> @@ -1837,7 +1750,7 @@ FindFile (
>      // If the found file is a symlink, then find its respective FE/EFE and
>      // FID descriptors.
>      //
> -    if (IS_FE_SYMLINK (File->FileEntry)) {
> +    if (FE_ICB_FILE_TYPE (File->FileEntry) == UdfFileEntrySymlink) {
>        FreePool ((VOID *)File->FileIdentifierDesc);
> 
>        FileEntry = File->FileEntry;
> @@ -1951,7 +1864,7 @@ ReadDirectoryEntry (
>      // Update FidOffset to point to next FID.
>      //
>      ReadDirInfo->FidOffset += GetFidDescriptorLength (FileIdentifierDesc);
> -  } while (IS_FID_DELETED_FILE (FileIdentifierDesc));
> +  } while (FileIdentifierDesc->FileCharacteristics & DELETED_FILE);
> 
>    DuplicateFid (FileIdentifierDesc, FoundFid);
> 
> @@ -2197,43 +2110,6 @@ Error_Find_File:
>  }
> 
>  /**
> -  Clean up in-memory UDF volume information.
> -
> -  @param[in] Volume Volume information pointer.
> -
> -**/
> -VOID
> -CleanupVolumeInformation (
> -  IN UDF_VOLUME_INFO *Volume
> -  )
> -{
> -  UINTN Index;
> -
> -  if (Volume->LogicalVolDescs != NULL) {
> -    for (Index = 0; Index < Volume->LogicalVolDescsNo; Index++) {
> -      FreePool ((VOID *)Volume->LogicalVolDescs[Index]);
> -    }
> -    FreePool ((VOID *)Volume->LogicalVolDescs);
> -  }
> -
> -  if (Volume->PartitionDescs != NULL) {
> -    for (Index = 0; Index < Volume->PartitionDescsNo; Index++) {
> -      FreePool ((VOID *)Volume->PartitionDescs[Index]);
> -    }
> -    FreePool ((VOID *)Volume->PartitionDescs);
> -  }
> -
> -  if (Volume->FileSetDescs != NULL) {
> -    for (Index = 0; Index < Volume->FileSetDescsNo; Index++) {
> -      FreePool ((VOID *)Volume->FileSetDescs[Index]);
> -    }
> -    FreePool ((VOID *)Volume->FileSetDescs);
> -  }
> -
> -  ZeroMem ((VOID *)Volume, sizeof (UDF_VOLUME_INFO));
> -}
> -
> -/**
>    Clean up in-memory UDF file information.
> 
>    @param[in] File File information pointer.
> @@ -2333,6 +2209,7 @@ SetFileInfo (
>    EFI_FILE_INFO            *FileInfo;
>    UDF_FILE_ENTRY           *FileEntry;
>    UDF_EXTENDED_FILE_ENTRY  *ExtendedFileEntry;
> +  UDF_DESCRIPTOR_TAG       *DescriptorTag;
> 
>    //
>    // Calculate the needed size for the EFI_FILE_INFO structure.
> @@ -2367,7 +2244,9 @@ SetFileInfo (
>      FileInfo->Attribute |= EFI_FILE_HIDDEN;
>    }
> 
> -  if (IS_FE (File->FileEntry)) {
> +  DescriptorTag = File->FileEntry;
> +
> +  if (UDF_TAG_ID (DescriptorTag) == UdfFileEntry) {
>      FileEntry = (UDF_FILE_ENTRY *)File->FileEntry;
> 
>      //
> @@ -2403,7 +2282,7 @@ SetFileInfo (
>                                     FileEntry->AccessTime.Second;
>      FileInfo->LastAccessTime.Nanosecond  =
>                                     FileEntry->AccessTime.HundredsOfMicroseconds;
> -  } else if (IS_EFE (File->FileEntry)) {
> +  } else if (UDF_TAG_ID (DescriptorTag) == UdfExtendedFileEntry) {
>      ExtendedFileEntry = (UDF_EXTENDED_FILE_ENTRY *)File->FileEntry;
> 
>      //
> @@ -2487,91 +2366,103 @@ GetVolumeSize (
>    OUT  UINT64                 *FreeSpaceSize
>    )
>  {
> -  UDF_EXTENT_AD                 ExtentAd;
> -  UINT32                        LogicalBlockSize;
> -  UINT64                        Lsn;
> -  EFI_STATUS                    Status;
> -  UDF_LOGICAL_VOLUME_INTEGRITY  *LogicalVolInt;
> -  UINTN                         Index;
> -  UINTN                         Length;
> -  UINT32                        LsnsNo;
> -
> -  *VolumeSize     = 0;
> -  *FreeSpaceSize  = 0;
> -
> -  for (Index = 0; Index < Volume->LogicalVolDescsNo; Index++) {
> -    CopyMem ((VOID *)&ExtentAd,
> -             (VOID *)&Volume->LogicalVolDescs[Index]->IntegritySequenceExtent,
> -             sizeof (UDF_EXTENT_AD));
> -    if (ExtentAd.ExtentLength == 0) {
> -      continue;
> -    }
> +  EFI_STATUS                     Status;
> +  UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;
> +  UDF_EXTENT_AD                  *ExtentAd;
> +  UINT64                         Lsn;
> +  UINT32                         LogicalBlockSize;
> +  UDF_LOGICAL_VOLUME_INTEGRITY   *LogicalVolInt;
> +  UDF_DESCRIPTOR_TAG             *DescriptorTag;
> +  UINTN                          Index;
> +  UINTN                          Length;
> +  UINT32                         LsnsNo;
> 
> -    LogicalBlockSize = LV_BLOCK_SIZE (Volume, Index);
> +  LogicalVolDesc = &Volume->LogicalVolDesc;
> 
> -  Read_Next_Sequence:
> -    LogicalVolInt = (UDF_LOGICAL_VOLUME_INTEGRITY *)
> -      AllocatePool (ExtentAd.ExtentLength);
> -    if (LogicalVolInt == NULL) {
> -      return EFI_OUT_OF_RESOURCES;
> -    }
> +  ExtentAd = &LogicalVolDesc->IntegritySequenceExtent;
> +
> +  if (ExtentAd->ExtentLength == 0) {
> +    return EFI_VOLUME_CORRUPTED;
> +  }
> 
> -    Lsn = (UINT64)ExtentAd.ExtentLocation;
> +  LogicalVolInt = AllocatePool (ExtentAd->ExtentLength);
> +  if (LogicalVolInt == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> 
> -    Status = DiskIo->ReadDisk (
> -      DiskIo,
> -      BlockIo->Media->MediaId,
> -      MultU64x32 (Lsn, LogicalBlockSize),
> -      ExtentAd.ExtentLength,
> -      (VOID *)LogicalVolInt
> -      );
> -    if (EFI_ERROR (Status)) {
> -      FreePool ((VOID *)LogicalVolInt);
> -      return Status;
> -    }
> +  //
> +  // Get location of Logical Volume Integrity Descriptor
> +  //
> +  Lsn = (UINT64)ExtentAd->ExtentLocation - Volume->MainVdsStartLocation;
> 
> -    if (!IS_LVID (LogicalVolInt)) {
> -      FreePool ((VOID *)LogicalVolInt);
> -      return EFI_VOLUME_CORRUPTED;
> -    }
> +  LogicalBlockSize = LogicalVolDesc->LogicalBlockSize;
> 
> -    Length = LogicalVolInt->NumberOfPartitions;
> -    for (Index = 0; Index < Length; Index += sizeof (UINT32)) {
> -      LsnsNo = *(UINT32 *)((UINT8 *)LogicalVolInt->Data + Index);
> -      if (LsnsNo == 0xFFFFFFFFUL) {
> -        //
> -        // Size not specified.
> -        //
> -        continue;
> -      }
> +  //
> +  // Read disk block
> +  //
> +  Status = DiskIo->ReadDisk (
> +    DiskIo,
> +    BlockIo->Media->MediaId,
> +    MultU64x32 (Lsn, LogicalBlockSize),
> +    ExtentAd->ExtentLength,
> +    LogicalVolInt
> +    );
> +  if (EFI_ERROR (Status)) {
> +    goto Out_Free;
> +  }
> 
> -      *FreeSpaceSize += MultU64x32 ((UINT64)LsnsNo, LogicalBlockSize);
> -    }
> +  DescriptorTag = &LogicalVolInt->DescriptorTag;
> 
> -    Length = (LogicalVolInt->NumberOfPartitions * sizeof (UINT32)) << 1;
> -    for (; Index < Length; Index += sizeof (UINT32)) {
> -      LsnsNo = *(UINT32 *)((UINT8 *)LogicalVolInt->Data + Index);
> -      if (LsnsNo == 0xFFFFFFFFUL) {
> -        //
> -        // Size not specified.
> -        //
> -        continue;
> -      }
> +  //
> +  // Check if read block is a Logical Volume Integrity Descriptor
> +  //
> +  if (UDF_TAG_ID (DescriptorTag) != UdfLogicalVolumeIntegrityDescriptor) {
> +    Status = EFI_VOLUME_CORRUPTED;
> +    goto Out_Free;
> +  }
> 
> -      *VolumeSize += MultU64x32 ((UINT64)LsnsNo, LogicalBlockSize);
> -    }
> +  *VolumeSize = 0;
> +  *FreeSpaceSize = 0;
> 
> -    CopyMem ((VOID *)&ExtentAd,(VOID *)&LogicalVolInt->NextIntegrityExtent,
> -             sizeof (UDF_EXTENT_AD));
> -    if (ExtentAd.ExtentLength > 0) {
> -      FreePool ((VOID *)LogicalVolInt);
> -      goto Read_Next_Sequence;
> +  Length = LogicalVolInt->NumberOfPartitions;
> +  for (Index = 0; Index < Length; Index += sizeof (UINT32)) {
> +    LsnsNo = *(UINT32 *)((UINT8 *)LogicalVolInt->Data + Index);
> +    //
> +    // Check if size is not specified
> +    //
> +    if (LsnsNo == 0xFFFFFFFFUL) {
> +      continue;
>      }
> +    //
> +    // Accumulate free space size
> +    //
> +    *FreeSpaceSize += MultU64x32 ((UINT64)LsnsNo, LogicalBlockSize);
> +  }
> 
> -    FreePool ((VOID *)LogicalVolInt);
> +  Length = LogicalVolInt->NumberOfPartitions * sizeof (UINT32) * 2;
> +  for (; Index < Length; Index += sizeof (UINT32)) {
> +    LsnsNo = *(UINT32 *)((UINT8 *)LogicalVolInt->Data + Index);
> +    //
> +    // Check if size is not specified
> +    //
> +    if (LsnsNo == 0xFFFFFFFFUL) {
> +      continue;
> +    }
> +    //
> +    // Accumulate used volume space
> +    //
> +    *VolumeSize += MultU64x32 ((UINT64)LsnsNo, LogicalBlockSize);
>    }
> 
> -  return EFI_SUCCESS;
> +  Status = EFI_SUCCESS;
> +
> +Out_Free:
> +  //
> +  // Free Logical Volume Integrity Descriptor
> +  //
> +  FreePool (LogicalVolInt);
> +
> +  return Status;
>  }
> 
>  /**
> diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/Udf.c
> b/MdeModulePkg/Universal/Disk/UdfDxe/Udf.c
> index 49dc7077b7..d4163b89ca 100644
> --- a/MdeModulePkg/Universal/Disk/UdfDxe/Udf.c
> +++ b/MdeModulePkg/Universal/Disk/UdfDxe/Udf.c
> @@ -276,13 +276,6 @@ UdfDriverBindingStop (
>        NULL
>        );
> 
> -    //
> -    // Check if there's any open file. If so, clean them up.
> -    //
> -    if (PrivFsData->OpenFiles > 0) {
> -      CleanupVolumeInformation (&PrivFsData->Volume);
> -    }
> -
>      FreePool ((VOID *)PrivFsData);
>    }
> 
> diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/Udf.h
> b/MdeModulePkg/Universal/Disk/UdfDxe/Udf.h
> index 44c843fd4d..ef2a3359ce 100644
> --- a/MdeModulePkg/Universal/Disk/UdfDxe/Udf.h
> +++ b/MdeModulePkg/Universal/Disk/UdfDxe/Udf.h
> @@ -49,61 +49,34 @@
>      { 0x89, 0x56, 0x73, 0xCD, 0xA3, 0x26, 0xCD, 0x0A }  \
>    }
> 
> -#define UDF_DEFAULT_LV_NUM 0
> -
> -#define IS_PVD(_Pointer) \
> -  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 1))
> -#define IS_PD(_Pointer) \
> -  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 5))
> -#define IS_LVD(_Pointer) \
> -  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 6))
> -#define IS_TD(_Pointer) \
> -  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 8))
> -#define IS_FSD(_Pointer) \
> -  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 256))
> -#define IS_FE(_Pointer) \
> -  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 261))
> -#define IS_EFE(_Pointer) \
> -  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 266))
> -#define IS_FID(_Pointer) \
> -  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 257))
> -#define IS_AED(_Pointer) \
> -  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 258))
> -#define IS_LVID(_Pointer) \
> -  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 9))
> -
> -#define _GET_FILETYPE(_Pointer) \
> -  (IS_FE (_Pointer) ? \
> -   (((UDF_FILE_ENTRY *)(_Pointer))->IcbTag.FileType) \
> -   : \
> -   (((UDF_EXTENDED_FILE_ENTRY *)(_Pointer))->IcbTag.FileType))
> -
> -#define IS_FE_DIRECTORY(_Pointer) \
> -  ((BOOLEAN)(_GET_FILETYPE (_Pointer) == 4))
> -#define IS_FE_STANDARD_FILE(_Pointer) \
> -  ((BOOLEAN)(_GET_FILETYPE (_Pointer) == 5))
> -#define IS_FE_SYMLINK(_Pointer) \
> -  ((BOOLEAN)(_GET_FILETYPE (_Pointer) == 12))
> +#define FE_ICB_FILE_TYPE(_Ptr) \
> +  (UDF_FILE_ENTRY_TYPE)( \
> +  (UDF_TAG_ID ((UDF_DESCRIPTOR_TAG *)(_Ptr)) == UdfFileEntry ? \
> +   ((UDF_FILE_ENTRY *)(_Ptr))->IcbTag.FileType : \
> +   ((UDF_EXTENDED_FILE_ENTRY *)(_Ptr))->IcbTag.FileType))
> +
> +typedef enum {
> +  UdfFileEntryDirectory = 4,
> +  UdfFileEntryStandardFile = 5,
> +  UdfFileEntrySymlink = 12,
> +} UDF_FILE_ENTRY_TYPE;
> 
>  #define HIDDEN_FILE     (1 << 0)
>  #define DIRECTORY_FILE  (1 << 1)
>  #define DELETED_FILE    (1 << 2)
>  #define PARENT_FILE     (1 << 3)
> 
> -#define _GET_FILE_CHARS(_Pointer) \
> -  (((UDF_FILE_IDENTIFIER_DESCRIPTOR *)(_Pointer))->FileCharacteristics)
> -
> -#define IS_FID_HIDDEN_FILE(_Pointer) \
> -  ((BOOLEAN)(_GET_FILE_CHARS (_Pointer) & HIDDEN_FILE))
> -#define IS_FID_DIRECTORY_FILE(_Pointer) \
> -  ((BOOLEAN)(_GET_FILE_CHARS (_Pointer) & DIRECTORY_FILE))
> -#define IS_FID_DELETED_FILE(_Pointer) \
> -  ((BOOLEAN)(_GET_FILE_CHARS (_Pointer) & DELETED_FILE))
> -#define IS_FID_PARENT_FILE(_Pointer) \
> -  ((BOOLEAN)(_GET_FILE_CHARS (_Pointer) & PARENT_FILE))
> -#define IS_FID_NORMAL_FILE(_Pointer) \
> -  ((BOOLEAN)(!IS_FID_DIRECTORY_FILE (_Pointer) && \
> -         !IS_FID_PARENT_FILE (_Pointer)))
> +#define IS_FID_HIDDEN_FILE(_Fid) \
> +  (BOOLEAN)((_Fid)->FileCharacteristics & HIDDEN_FILE)
> +#define IS_FID_DIRECTORY_FILE(_Fid) \
> +  (BOOLEAN)((_Fid)->FileCharacteristics & DIRECTORY_FILE)
> +#define IS_FID_DELETED_FILE(_Fid) \
> +  (BOOLEAN)((_Fid)->FileCharacteristics & DELETED_FILE)
> +#define IS_FID_PARENT_FILE(_Fid) \
> +  (BOOLEAN)((_Fid)->FileCharacteristics & PARENT_FILE)
> +#define IS_FID_NORMAL_FILE(_Fid) \
> +  (BOOLEAN)(!IS_FID_DIRECTORY_FILE (_Fid) && \
> +            !IS_FID_PARENT_FILE (_Fid))
> 
>  typedef enum {
>    ShortAdsSequence,
> @@ -152,14 +125,8 @@ typedef enum {
>  #define IS_VALID_COMPRESSION_ID(_CompId) \
>    ((BOOLEAN)((_CompId) == 8 || (_CompId) == 16))
> 
> -#define LV_BLOCK_SIZE(_Vol, _LvNum) \
> -  (_Vol)->LogicalVolDescs[(_LvNum)]->LogicalBlockSize
> -
>  #define UDF_STANDARD_IDENTIFIER_LENGTH   5
> 
> -#define LV_UDF_REVISION(_Lv) \
> -  *(UINT16 *)(UINTN)(_Lv)->DomainIdentifier.IdentifierSuffix
> -
>  #pragma pack(1)
> 
>  typedef struct {
> @@ -186,17 +153,6 @@ typedef struct {
>  #pragma pack(1)
> 
>  typedef struct {
> -  UINT8           CharacterSetType;
> -  UINT8           CharacterSetInfo[63];
> -} UDF_CHAR_SPEC;
> -
> -typedef struct {
> -  UINT8           Flags;
> -  UINT8           Identifier[23];
> -  UINT8           IdentifierSuffix[8];
> -} UDF_ENTITY_ID;
> -
> -typedef struct {
>    UINT16          TypeAndTimezone;
>    INT16           Year;
>    UINT8           Month;
> @@ -210,17 +166,6 @@ typedef struct {
>  } UDF_TIMESTAMP;
> 
>  typedef struct {
> -  UINT32        LogicalBlockNumber;
> -  UINT16        PartitionReferenceNumber;
> -} UDF_LB_ADDR;
> -
> -typedef struct {
> -  UINT32                           ExtentLength;
> -  UDF_LB_ADDR                      ExtentLocation;
> -  UINT8                            ImplementationUse[6];
> -} UDF_LONG_ALLOCATION_DESCRIPTOR;
> -
> -typedef struct {
>    UDF_DESCRIPTOR_TAG                 DescriptorTag;
>    UINT32                             PrevAllocationExtentDescriptor;
>    UINT32                             LengthOfAllocationDescriptors;
> @@ -235,6 +180,17 @@ typedef struct {
>  } UDF_VOLUME_DESCRIPTOR;
> 
>  typedef struct {
> +  UDF_DESCRIPTOR_TAG             DescriptorTag;
> +  UDF_TIMESTAMP                  RecordingDateTime;
> +  UINT32                         IntegrityType;
> +  UDF_EXTENT_AD                  NextIntegrityExtent;
> +  UINT8                          LogicalVolumeContentsUse[32];
> +  UINT32                         NumberOfPartitions;
> +  UINT32                         LengthOfImplementationUse;
> +  UINT8                          Data[0];
> +} UDF_LOGICAL_VOLUME_INTEGRITY;
> +
> +typedef struct {
>    UDF_DESCRIPTOR_TAG         DescriptorTag;
>    UINT32                     VolumeDescriptorSequenceNumber;
>    UINT16                     PartitionFlags;
> @@ -251,33 +207,6 @@ typedef struct {
> 
>  typedef struct {
>    UDF_DESCRIPTOR_TAG              DescriptorTag;
> -  UINT32                          VolumeDescriptorSequenceNumber;
> -  UDF_CHAR_SPEC                   DescriptorCharacterSet;
> -  UINT8                           LogicalVolumeIdentifier[128];
> -  UINT32                          LogicalBlockSize;
> -  UDF_ENTITY_ID                   DomainIdentifier;
> -  UDF_LONG_ALLOCATION_DESCRIPTOR  LogicalVolumeContentsUse;
> -  UINT32                          MapTableLength;
> -  UINT32                          NumberOfPartitionMaps;
> -  UDF_ENTITY_ID                   ImplementationIdentifier;
> -  UINT8                           ImplementationUse[128];
> -  UDF_EXTENT_AD                   IntegritySequenceExtent;
> -  UINT8                           PartitionMaps[6];
> -} UDF_LOGICAL_VOLUME_DESCRIPTOR;
> -
> -typedef struct {
> -  UDF_DESCRIPTOR_TAG             DescriptorTag;
> -  UDF_TIMESTAMP                  RecordingDateTime;
> -  UINT32                         IntegrityType;
> -  UDF_EXTENT_AD                  NextIntegrityExtent;
> -  UINT8                          LogicalVolumeContentsUse[32];
> -  UINT32                         NumberOfPartitions;
> -  UINT32                         LengthOfImplementationUse;
> -  UINT8                          Data[0];
> -} UDF_LOGICAL_VOLUME_INTEGRITY;
> -
> -typedef struct {
> -  UDF_DESCRIPTOR_TAG              DescriptorTag;
>    UDF_TIMESTAMP                   RecordingDateAndTime;
>    UINT16                          InterchangeLevel;
>    UINT16                          MaximumInterchangeLevel;
> @@ -389,12 +318,10 @@ typedef struct {
>  // UDF filesystem driver's private data
>  //
>  typedef struct {
> -  UDF_LOGICAL_VOLUME_DESCRIPTOR  **LogicalVolDescs;
> -  UINTN                          LogicalVolDescsNo;
> -  UDF_PARTITION_DESCRIPTOR       **PartitionDescs;
> -  UINTN                          PartitionDescsNo;
> -  UDF_FILE_SET_DESCRIPTOR        **FileSetDescs;
> -  UINTN                          FileSetDescsNo;
> +  UINT64                         MainVdsStartLocation;
> +  UDF_LOGICAL_VOLUME_DESCRIPTOR  LogicalVolDesc;
> +  UDF_PARTITION_DESCRIPTOR       PartitionDesc;
> +  UDF_FILE_SET_DESCRIPTOR        FileSetDesc;
>    UINTN                          FileEntrySize;
>  } UDF_VOLUME_INFO;
> 
> @@ -884,17 +811,6 @@ ResolveSymlink (
>    );
> 
>  /**
> -  Clean up in-memory UDF volume information.
> -
> -  @param[in] Volume Volume information pointer.
> -
> -**/
> -VOID
> -CleanupVolumeInformation (
> -  IN UDF_VOLUME_INFO *Volume
> -  );
> -
> -/**
>    Clean up in-memory UDF file information.
> 
>    @param[in] File File information pointer.
> --
> 2.11.0
> 
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Re: [edk2] [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix creation of UDF logical partition
Posted by Paulo Alcantara 7 years, 3 months ago

On September 21, 2017 9:44:10 AM GMT-03:00, "Wu, Hao A" <hao.a.wu@intel.com> wrote:
>One small comment, within function PartitionInstallUdfChildHandles():
>
>  ...
>  //
>  // Install partition child handle for UDF file system
>  //
>  Status = PartitionInstallChildHandle (
>    ...
>    );
>if (!EFI_ERROR (Status)) {  <----- Is this a typo? "if (EFI_ERROR
>(Status)) {"  
>    Status = EFI_NOT_FOUND;
>  }

Yes, it is. Good catch! Could you please fix that for me by removing the if condition? Otherwise I can send a v4 later with that.

Thanks!
Paulo

>  
>
>Best Regards,
>Hao Wu
>
>
>> -----Original Message-----
>> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf
>Of Paulo
>> Alcantara
>> Sent: Thursday, September 21, 2017 2:16 AM
>> To: edk2-devel@lists.01.org
>> Cc: Ni, Ruiyu; Laszlo Ersek; Dong, Eric; Zeng, Star
>> Subject: [edk2] [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix
>creation of
>> UDF logical partition
>> 
>> Do not reserve entire block device size for an UDF file system -
>> instead, reserve the appropriate space (UDF logical volume space) for
>> it.
>> 
>> Additionally, only create a logical partition for UDF logical volumes
>> that are currently supported by EDK2 UDF file system implementation.
>For
>> instance, an UDF volume with a single LVD and a single Physical (Type
>1)
>> Partition will be supported.
>> 
>> Cc: Eric Dong <eric.dong@intel.com>
>> Cc: Ruiyu Ni <ruiyu.ni@intel.com>
>> Cc: Star Zeng <star.zeng@intel.com>
>> Cc: Laszlo Ersek <lersek@redhat.com>
>> Reported-by: Ruiyu Ni <ruiyu.ni@intel.com>
>> Contributed-under: TianoCore Contribution Agreement 1.1
>> Signed-off-by: Paulo Alcantara <pcacjr@zytor.com>
>> ---
>>  MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c            | 363
>++++++++++--
>>  MdeModulePkg/Universal/Disk/UdfDxe/File.c                 |  16 +-
>>  MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c | 627
>> ++++++++------------
>>  MdeModulePkg/Universal/Disk/UdfDxe/Udf.c                  |   7 -
>>  MdeModulePkg/Universal/Disk/UdfDxe/Udf.h                  | 158
>++---
>>  5 files changed, 606 insertions(+), 565 deletions(-)
>> 
>> diff --git a/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
>> b/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
>> index 609f56cef6..572ba7a81a 100644
>> --- a/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
>> +++ b/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
>> @@ -64,11 +64,12 @@ FindAnchorVolumeDescriptorPointer (
>>    OUT  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint
>>    )
>>  {
>> -  EFI_STATUS  Status;
>> -  UINT32      BlockSize;
>> -  EFI_LBA     EndLBA;
>> -  EFI_LBA     DescriptorLBAs[4];
>> -  UINTN       Index;
>> +  EFI_STATUS          Status;
>> +  UINT32              BlockSize;
>> +  EFI_LBA             EndLBA;
>> +  EFI_LBA             DescriptorLBAs[4];
>> +  UINTN               Index;
>> +  UDF_DESCRIPTOR_TAG  *DescriptorTag;
>> 
>>    BlockSize = BlockIo->Media->BlockSize;
>>    EndLBA = BlockIo->Media->LastBlock;
>> @@ -88,10 +89,13 @@ FindAnchorVolumeDescriptorPointer (
>>      if (EFI_ERROR (Status)) {
>>        return Status;
>>      }
>> +
>> +    DescriptorTag = &AnchorPoint->DescriptorTag;
>> +
>>      //
>>      // Check if read LBA has a valid AVDP descriptor.
>>      //
>> -    if (IS_AVDP (AnchorPoint)) {
>> +    if (DescriptorTag->TagIdentifier ==
>UdfAnchorVolumeDescriptorPointer) {
>>        return EFI_SUCCESS;
>>      }
>>    }
>> @@ -102,23 +106,18 @@ FindAnchorVolumeDescriptorPointer (
>>  }
>> 
>>  /**
>> -  Check if block device supports a valid UDF file system as
>specified by OSTA
>> -  Universal Disk Format Specification 2.60.
>> +  Find UDF volume identifiers in a Volume Recognition Sequence.
>> 
>> -  @param[in]   BlockIo  BlockIo interface.
>> -  @param[in]   DiskIo   DiskIo interface.
>> +  @param[in]  BlockIo             BlockIo interface.
>> +  @param[in]  DiskIo              DiskIo interface.
>> 
>> -  @retval EFI_SUCCESS          UDF file system found.
>> -  @retval EFI_UNSUPPORTED      UDF file system not found.
>> -  @retval EFI_NO_MEDIA         The device has no media.
>> -  @retval EFI_DEVICE_ERROR     The device reported an error.
>> -  @retval EFI_VOLUME_CORRUPTED The file system structures are
>corrupted.
>> -  @retval EFI_OUT_OF_RESOURCES The scan was not successful due to
>lack of
>> -                               resources.
>> +  @retval EFI_SUCCESS             UDF volume identifiers were found.
>> +  @retval EFI_NOT_FOUND           UDF volume identifiers were not
>found.
>> +  @retval other                   Failed to perform disk I/O.
>> 
>>  **/
>>  EFI_STATUS
>> -SupportUdfFileSystem (
>> +FindUdfVolumeIdentifiers (
>>    IN EFI_BLOCK_IO_PROTOCOL  *BlockIo,
>>    IN EFI_DISK_IO_PROTOCOL   *DiskIo
>>    )
>> @@ -128,7 +127,6 @@ SupportUdfFileSystem (
>>    UINT64                                EndDiskOffset;
>>    CDROM_VOLUME_DESCRIPTOR               VolDescriptor;
>>    CDROM_VOLUME_DESCRIPTOR               TerminatingVolDescriptor;
>> -  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  AnchorPoint;
>> 
>>    ZeroMem ((VOID *)&TerminatingVolDescriptor, sizeof
>> (CDROM_VOLUME_DESCRIPTOR));
>> 
>> @@ -167,7 +165,7 @@ SupportUdfFileSystem (
>>          (CompareMem ((VOID *)&VolDescriptor,
>>                       (VOID *)&TerminatingVolDescriptor,
>>                       sizeof (CDROM_VOLUME_DESCRIPTOR)) == 0)) {
>> -      return EFI_UNSUPPORTED;
>> +      return EFI_NOT_FOUND;
>>      }
>>    }
>> 
>> @@ -176,7 +174,7 @@ SupportUdfFileSystem (
>>    //
>>    Offset += UDF_LOGICAL_SECTOR_SIZE;
>>    if (Offset >= EndDiskOffset) {
>> -    return EFI_UNSUPPORTED;
>> +    return EFI_NOT_FOUND;
>>    }
>> 
>>    Status = DiskIo->ReadDisk (
>> @@ -196,7 +194,7 @@ SupportUdfFileSystem (
>>        (CompareMem ((VOID *)VolDescriptor.Unknown.Id,
>>                     (VOID *)UDF_NSR3_IDENTIFIER,
>>                     sizeof (VolDescriptor.Unknown.Id)) != 0)) {
>> -    return EFI_UNSUPPORTED;
>> +    return EFI_NOT_FOUND;
>>    }
>> 
>>    //
>> @@ -204,7 +202,7 @@ SupportUdfFileSystem (
>>    //
>>    Offset += UDF_LOGICAL_SECTOR_SIZE;
>>    if (Offset >= EndDiskOffset) {
>> -    return EFI_UNSUPPORTED;
>> +    return EFI_NOT_FOUND;
>>    }
>> 
>>    Status = DiskIo->ReadDisk (
>> @@ -221,15 +219,291 @@ SupportUdfFileSystem (
>>    if (CompareMem ((VOID *)VolDescriptor.Unknown.Id,
>>                    (VOID *)UDF_TEA_IDENTIFIER,
>>                    sizeof (VolDescriptor.Unknown.Id)) != 0) {
>> -    return EFI_UNSUPPORTED;
>> +    return EFI_NOT_FOUND;
>> +  }
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +/**
>> +  Check if Logical Volume Descriptor is supported by current EDK2
>UDF file
>> +  system implementation.
>> +
>> +  @param[in]  LogicalVolDesc  Logical Volume Descriptor pointer.
>> +
>> +  @retval TRUE                Logical Volume Descriptor is
>supported.
>> +  @retval FALSE               Logical Volume Descriptor is not
>supported.
>> +
>> +**/
>> +BOOLEAN
>> +IsLogicalVolumeDescriptorSupported (
>> +  UDF_LOGICAL_VOLUME_DESCRIPTOR *LogicalVolDesc
>> +  )
>> +{
>> +  //
>> +  // Check for a valid UDF revision range
>> +  //
>> +  switch (UDF_LVD_REVISION (LogicalVolDesc)) {
>> +  case 0x0102:
>> +  case 0x0150:
>> +  case 0x0200:
>> +  case 0x0201:
>> +  case 0x0250:
>> +  case 0x0260:
>> +    break;
>> +  default:
>> +    return FALSE;
>> +  }
>> +
>> +  //
>> +  // Check for a single Partition Map
>> +  //
>> +  if (LogicalVolDesc->NumberOfPartitionMaps > 1) {
>> +    return FALSE;
>> +  }
>> +  //
>> +  // UDF 1.02 revision supports only Type 1 (Physical) partitions,
>but
>> +  // let's check it any way.
>> +  //
>> +  // PartitionMap[0] -> type
>> +  // PartitionMap[1] -> length (in bytes)
>> +  //
>> +  if (LogicalVolDesc->PartitionMaps[0] != 1 ||
>> +      LogicalVolDesc->PartitionMaps[1] != 6) {
>> +    return FALSE;
>> +  }
>> +
>> +  return TRUE;
>> +}
>> +
>> +/**
>> +  Find UDF logical volume location and whether it is supported by
>current EDK2
>> +  UDF file system implementation.
>> +
>> +  @param[in]  BlockIo             BlockIo interface.
>> +  @param[in]  DiskIo              DiskIo interface.
>> +  @param[in]  AnchorPoint         Anchor volume descriptor pointer.
>> +  @param[out] MainVdsStartBlock   Main VDS starting block number.
>> +  @param[out] MainVdsEndBlock     Main VDS ending block number.
>> +
>> +  @retval EFI_SUCCESS             UDF logical volume was found.
>> +  @retval EFI_VOLUME_CORRUPTED    UDF file system structures are
>> corrupted.
>> +  @retval EFI_UNSUPPORTED         UDF logical volume is not
>supported.
>> +  @retval other                   Failed to perform disk I/O.
>> +
>> +**/
>> +EFI_STATUS
>> +FindLogicalVolumeLocation (
>> +  IN   EFI_BLOCK_IO_PROTOCOL                 *BlockIo,
>> +  IN   EFI_DISK_IO_PROTOCOL                  *DiskIo,
>> +  IN   UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint,
>> +  OUT  UINT64                                *MainVdsStartBlock,
>> +  OUT  UINT64                                *MainVdsEndBlock
>> +  )
>> +{
>> +  EFI_STATUS                     Status;
>> +  UINT32                         BlockSize;
>> +  EFI_LBA                        LastBlock;
>> +  UDF_EXTENT_AD                  *ExtentAd;
>> +  UINT64                         SeqBlocksNum;
>> +  UINT64                         SeqStartBlock;
>> +  UINT64                         GuardMainVdsStartBlock;
>> +  VOID                           *Buffer;
>> +  UINT64                         SeqEndBlock;
>> +  BOOLEAN                        StopSequence;
>> +  UINTN                          LvdsCount;
>> +  UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;
>> +  UDF_DESCRIPTOR_TAG             *DescriptorTag;
>> +
>> +  BlockSize = BlockIo->Media->BlockSize;
>> +  LastBlock = BlockIo->Media->LastBlock;
>> +  ExtentAd = &AnchorPoint->MainVolumeDescriptorSequenceExtent;
>> +
>> +  //
>> +  // UDF 2.60, 2.2.3.1 struct MainVolumeDescriptorSequenceExtent
>> +  //
>> +  // The Main Volume Descriptor Sequence Extent shall have a minimum
>length
>> of
>> +  // 16 logical sectors.
>> +  //
>> +  // Also make sure it does not exceed maximum number of blocks in
>the disk.
>> +  //
>> +  SeqBlocksNum = DivU64x32 ((UINT64)ExtentAd->ExtentLength,
>BlockSize);
>> +  if (SeqBlocksNum < 16 || (EFI_LBA)SeqBlocksNum > LastBlock + 1) {
>> +    return EFI_VOLUME_CORRUPTED;
>> +  }
>> +
>> +  //
>> +  // Check for valid Volume Descriptor Sequence starting block
>number
>> +  //
>> +  SeqStartBlock = (UINT64)ExtentAd->ExtentLocation;
>> +  if (SeqStartBlock > LastBlock ||
>> +      SeqStartBlock + SeqBlocksNum - 1 > LastBlock) {
>> +    return EFI_VOLUME_CORRUPTED;
>>    }
>> 
>> +  GuardMainVdsStartBlock = SeqStartBlock;
>> +
>> +  //
>> +  // Allocate buffer for reading disk blocks
>> +  //
>> +  Buffer = AllocateZeroPool ((UINTN)BlockSize);
>> +  if (Buffer == NULL) {
>> +    return EFI_OUT_OF_RESOURCES;
>> +  }
>> +
>> +  SeqEndBlock = SeqStartBlock + SeqBlocksNum;
>> +  StopSequence = FALSE;
>> +  LvdsCount = 0;
>> +  Status = EFI_VOLUME_CORRUPTED;
>> +  //
>> +  // Start Main Volume Descriptor Sequence
>> +  //
>> +  for (; SeqStartBlock < SeqEndBlock && !StopSequence;
>SeqStartBlock++) {
>> +    //
>> +    // Read disk block
>> +    //
>> +    Status = BlockIo->ReadBlocks (
>> +      BlockIo,
>> +      BlockIo->Media->MediaId,
>> +      SeqStartBlock,
>> +      BlockSize,
>> +      Buffer
>> +      );
>> +    if (EFI_ERROR (Status)) {
>> +      goto Out_Free;
>> +    }
>> +
>> +    DescriptorTag = Buffer;
>> +
>> +    //
>> +    // ECMA 167, 8.4.1 Contents of a Volume Descriptor Sequence
>> +    //
>> +    // - A Volume Descriptor Sequence shall contain one or more
>Primary
>> Volume
>> +    //   Descriptors.
>> +    // - A Volume Descriptor Sequence shall contain zero or more
>> Implementation
>> +    //   Use Volume Descriptors.
>> +    // - A Volume Descriptor Sequence shall contain zero or more
>Partition
>> +    //   Descriptors.
>> +    // - A Volume Descriptor Sequence shall contain zero or more
>Logical
>> Volume
>> +    //   Descriptors.
>> +    // - A Volume Descriptor Sequence shall contain zero or more
>Unallocated
>> +    //   Space Descriptors.
>> +    //
>> +    switch (UDF_TAG_ID (DescriptorTag)) {
>> +    case UdfPrimaryVolumeDescriptor:
>> +    case UdfImplemenationUseVolumeDescriptor:
>> +    case UdfPartitionDescriptor:
>> +    case UdfUnallocatedSpaceDescriptor:
>> +      break;
>> +
>> +    case UdfLogicalVolumeDescriptor:
>> +      LogicalVolDesc = Buffer;
>> +
>> +      //
>> +      // Check for existence of a single LVD and whether it is
>supported by
>> +      // current EDK2 UDF file system implementation.
>> +      //
>> +      if (++LvdsCount > 1 ||
>> +          !IsLogicalVolumeDescriptorSupported (LogicalVolDesc)) {
>> +        Status = EFI_UNSUPPORTED;
>> +        StopSequence = TRUE;
>> +      }
>> +
>> +      break;
>> +
>> +    case UdfTerminatingDescriptor:
>> +      //
>> +      // Stop the sequence when we find a Terminating Descriptor
>> +      // (aka Unallocated Sector), se we don't have to walk all the
>unallocated
>> +      // area unnecessarily.
>> +      //
>> +      StopSequence = TRUE;
>> +      break;
>> +
>> +    default:
>> +      //
>> +      // An invalid Volume Descriptor has been found in the sequece.
>Volume is
>> +      // corrupted.
>> +      //
>> +      Status = EFI_VOLUME_CORRUPTED;
>> +      goto Out_Free;
>> +    }
>> +  }
>> +
>> +  //
>> +  // Check if LVD was found
>> +  //
>> +  if (!EFI_ERROR (Status) && LvdsCount == 1) {
>> +    *MainVdsStartBlock = GuardMainVdsStartBlock;
>> +    //
>> +    // We do not need to read either LVD or PD descriptors to know
>the last
>> +    // valid block in the found UDF file system. It's already
>LastBlock.
>> +    //
>> +    *MainVdsEndBlock = LastBlock;
>> +
>> +    Status = EFI_SUCCESS;
>> +  }
>> +
>> +Out_Free:
>> +  //
>> +  // Free block read buffer
>> +  //
>> +  FreePool (Buffer);
>> +
>> +  return Status;
>> +}
>> +
>> +/**
>> +  Find a supported UDF file system in block device.
>> +
>> +  @param[in]  BlockIo             BlockIo interface.
>> +  @param[in]  DiskIo              DiskIo interface.
>> +  @param[out] StartingLBA         UDF file system starting LBA.
>> +  @param[out] EndingLBA           UDF file system starting LBA.
>> +
>> +  @retval EFI_SUCCESS             UDF file system was found.
>> +  @retval other                   UDF file system was not found.
>> +
>> +**/
>> +EFI_STATUS
>> +FindUdfFileSystem (
>> +  IN EFI_BLOCK_IO_PROTOCOL  *BlockIo,
>> +  IN EFI_DISK_IO_PROTOCOL   *DiskIo,
>> +  OUT EFI_LBA               *StartingLBA,
>> +  OUT EFI_LBA               *EndingLBA
>> +  )
>> +{
>> +  EFI_STATUS Status;
>> +  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  AnchorPoint;
>> +
>> +  //
>> +  // Find UDF volume identifiers
>> +  //
>> +  Status = FindUdfVolumeIdentifiers (BlockIo, DiskIo);
>> +  if (EFI_ERROR (Status)) {
>> +    return Status;
>> +  }
>> +
>> +  //
>> +  // Find Anchor Volume Descriptor Pointer
>> +  //
>>    Status = FindAnchorVolumeDescriptorPointer (BlockIo, DiskIo,
>&AnchorPoint);
>>    if (EFI_ERROR (Status)) {
>> -    return EFI_UNSUPPORTED;
>> +    return Status;
>>    }
>> 
>> -  return EFI_SUCCESS;
>> +  //
>> +  // Find Logical Volume location
>> +  //
>> +  Status = FindLogicalVolumeLocation (
>> +    BlockIo,
>> +    DiskIo,
>> +    &AnchorPoint,
>> +    (UINT64 *)StartingLBA,
>> +    (UINT64 *)EndingLBA
>> +    );
>> +
>> +  return Status;
>>  }
>> 
>>  /**
>> @@ -263,9 +537,9 @@ PartitionInstallUdfChildHandles (
>>    UINT32                       RemainderByMediaBlockSize;
>>    EFI_STATUS                   Status;
>>    EFI_BLOCK_IO_MEDIA           *Media;
>> -  EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode;
>> -  EFI_GUID                     *VendorDefinedGuid;
>>    EFI_PARTITION_INFO_PROTOCOL  PartitionInfo;
>> +  EFI_LBA                      StartingLBA;
>> +  EFI_LBA                      EndingLBA;
>> 
>>    Media = BlockIo->Media;
>> 
>> @@ -281,35 +555,10 @@ PartitionInstallUdfChildHandles (
>>      return EFI_NOT_FOUND;
>>    }
>> 
>> -  DevicePathNode = DevicePath;
>> -  while (!IsDevicePathEnd (DevicePathNode)) {
>> -    //
>> -    // Do not allow checking for UDF file systems in CDROM "El
>Torito"
>> -    // partitions, and skip duplicate installation of UDF file
>system child
>> -    // nodes.
>> -    //
>> -    if (DevicePathType (DevicePathNode) == MEDIA_DEVICE_PATH) {
>> -      if (DevicePathSubType (DevicePathNode) == MEDIA_CDROM_DP) {
>> -        return EFI_NOT_FOUND;
>> -      }
>> -      if (DevicePathSubType (DevicePathNode) == MEDIA_VENDOR_DP) {
>> -        VendorDefinedGuid = (EFI_GUID *)((UINTN)DevicePathNode +
>> -                                         OFFSET_OF
>(VENDOR_DEVICE_PATH, Guid));
>> -        if (CompareGuid (VendorDefinedGuid, &gUdfDevPathGuid)) {
>> -          return EFI_NOT_FOUND;
>> -        }
>> -      }
>> -    }
>> -    //
>> -    // Try next device path node
>> -    //
>> -    DevicePathNode = NextDevicePathNode (DevicePathNode);
>> -  }
>> -
>>    //
>> -  // Check if block device supports an UDF file system
>> +  // Search for an UDF file system on block device
>>    //
>> -  Status = SupportUdfFileSystem (BlockIo, DiskIo);
>> +  Status = FindUdfFileSystem (BlockIo, DiskIo, &StartingLBA,
>&EndingLBA);
>>    if (EFI_ERROR (Status)) {
>>      return EFI_NOT_FOUND;
>>    }
>> @@ -334,8 +583,8 @@ PartitionInstallUdfChildHandles (
>>      DevicePath,
>>      (EFI_DEVICE_PATH_PROTOCOL *)&gUdfDevicePath,
>>      &PartitionInfo,
>> -    0,
>> -    Media->LastBlock,
>> +    StartingLBA,
>> +    EndingLBA,
>>      Media->BlockSize
>>      );
>>    if (!EFI_ERROR (Status)) {
>> diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/File.c
>> b/MdeModulePkg/Universal/Disk/UdfDxe/File.c
>> index 625f2c5637..6f07bf2066 100644
>> --- a/MdeModulePkg/Universal/Disk/UdfDxe/File.c
>> +++ b/MdeModulePkg/Universal/Disk/UdfDxe/File.c
>> @@ -131,7 +131,6 @@ Error_Alloc_Priv_File_Data:
>>    CleanupFileInformation (&PrivFsData->Root);
>> 
>>  Error_Find_Root_Dir:
>> -  CleanupVolumeInformation (&PrivFsData->Volume);
>> 
>>  Error_Read_Udf_Volume:
>>  Error_Invalid_Params:
>> @@ -429,7 +428,7 @@ UdfRead (
>>      }
>>      ASSERT (NewFileEntryData != NULL);
>> 
>> -    if (IS_FE_SYMLINK (NewFileEntryData)) {
>> +    if (FE_ICB_FILE_TYPE (NewFileEntryData) == UdfFileEntrySymlink)
>{
>>        Status = ResolveSymlink (
>>          BlockIo,
>>          DiskIo,
>> @@ -529,7 +528,6 @@ UdfClose (
>>    EFI_TPL                     OldTpl;
>>    EFI_STATUS                  Status;
>>    PRIVATE_UDF_FILE_DATA       *PrivFileData;
>> -  PRIVATE_UDF_SIMPLE_FS_DATA  *PrivFsData;
>> 
>>    OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
>> 
>> @@ -542,8 +540,6 @@ UdfClose (
>> 
>>    PrivFileData = PRIVATE_UDF_FILE_DATA_FROM_THIS (This);
>> 
>> -  PrivFsData = PRIVATE_UDF_SIMPLE_FS_DATA_FROM_THIS (PrivFileData-
>> >SimpleFs);
>> -
>>    if (!PrivFileData->IsRootDirectory) {
>>      CleanupFileInformation (&PrivFileData->File);
>> 
>> @@ -552,10 +548,6 @@ UdfClose (
>>      }
>>    }
>> 
>> -  if (--PrivFsData->OpenFiles == 0) {
>> -    CleanupVolumeInformation (&PrivFsData->Volume);
>> -  }
>> -
>>    FreePool ((VOID *)PrivFileData);
>> 
>>  Exit:
>> @@ -652,7 +644,7 @@ UdfGetPosition (
>>    // As per UEFI spec, if the file handle is a directory, then the
>current file
>>    // position has no meaning and the operation is not supported.
>>    //
>> -  if (IS_FID_DIRECTORY_FILE
>(&PrivFileData->File.FileIdentifierDesc)) {
>> +  if (IS_FID_DIRECTORY_FILE (PrivFileData->File.FileIdentifierDesc))
>{
>>      return  EFI_UNSUPPORTED;
>>    }
>> 
>> @@ -788,7 +780,7 @@ UdfGetInfo (
>>    } else if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid))
>{
>>      String = VolumeLabel;
>> 
>> -    FileSetDesc = PrivFsData->Volume.FileSetDescs[0];
>> +    FileSetDesc = &PrivFsData->Volume.FileSetDesc;
>> 
>>      OstaCompressed = &FileSetDesc->LogicalVolumeIdentifier[0];
>> 
>> @@ -847,7 +839,7 @@ UdfGetInfo (
>>      FileSystemInfo->Size        = FileSystemInfoLength;
>>      FileSystemInfo->ReadOnly    = TRUE;
>>      FileSystemInfo->BlockSize   =
>> -      LV_BLOCK_SIZE (&PrivFsData->Volume, UDF_DEFAULT_LV_NUM);
>> +      PrivFsData->Volume.LogicalVolDesc.LogicalBlockSize;
>>      FileSystemInfo->VolumeSize  = VolumeSize;
>>      FileSystemInfo->FreeSpace   = FreeSpaceSize;
>> 
>> diff --git
>a/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
>> b/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
>> index 5df267761f..62d817989f 100644
>> --- a/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
>> +++ b/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
>> @@ -38,11 +38,12 @@ FindAnchorVolumeDescriptorPointer (
>>    OUT  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint
>>    )
>>  {
>> -  EFI_STATUS  Status;
>> -  UINT32      BlockSize;
>> -  EFI_LBA     EndLBA;
>> -  EFI_LBA     DescriptorLBAs[4];
>> -  UINTN       Index;
>> +  EFI_STATUS          Status;
>> +  UINT32              BlockSize;
>> +  EFI_LBA             EndLBA;
>> +  EFI_LBA             DescriptorLBAs[4];
>> +  UINTN               Index;
>> +  UDF_DESCRIPTOR_TAG  *DescriptorTag;
>> 
>>    BlockSize = BlockIo->Media->BlockSize;
>>    EndLBA = BlockIo->Media->LastBlock;
>> @@ -62,10 +63,13 @@ FindAnchorVolumeDescriptorPointer (
>>      if (EFI_ERROR (Status)) {
>>        return Status;
>>      }
>> +
>> +    DescriptorTag = &AnchorPoint->DescriptorTag;
>> +
>>      //
>>      // Check if read LBA has a valid AVDP descriptor.
>>      //
>> -    if (IS_AVDP (AnchorPoint)) {
>> +    if (DescriptorTag->TagIdentifier ==
>UdfAnchorVolumeDescriptorPointer) {
>>        return EFI_SUCCESS;
>>      }
>>    }
>> @@ -99,148 +103,98 @@ StartMainVolumeDescriptorSequence (
>>    OUT  UDF_VOLUME_INFO                       *Volume
>>    )
>>  {
>> -  EFI_STATUS                     Status;
>> -  UINT32                         BlockSize;
>> -  UDF_EXTENT_AD                  *ExtentAd;
>> -  UINT64                         StartingLsn;
>> -  UINT64                         EndingLsn;
>> -  VOID                           *Buffer;
>> -  UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;
>> -  UDF_PARTITION_DESCRIPTOR       *PartitionDesc;
>> -  UINTN                          Index;
>> -  UINT32                         LogicalBlockSize;
>> +  EFI_STATUS            Status;
>> +  UINT32                BlockSize;
>> +  UDF_EXTENT_AD         *ExtentAd;
>> +  EFI_LBA               SeqStartBlock;
>> +  EFI_LBA               SeqEndBlock;
>> +  BOOLEAN               StopSequence;
>> +  VOID                  *Buffer;
>> +  UDF_DESCRIPTOR_TAG    *DescriptorTag;
>> +  UINT32                LogicalBlockSize;
>> +
>> +  BlockSize = BlockIo->Media->BlockSize;
>> +  ExtentAd = &AnchorPoint->MainVolumeDescriptorSequenceExtent;
>> 
>>    //
>> -  // We've already found an ADVP on the volume. It contains the
>extent
>> -  // (MainVolumeDescriptorSequenceExtent) where the Main Volume
>> Descriptor
>> -  // Sequence starts. Therefore, we'll look for Logical Volume
>Descriptors and
>> -  // Partitions Descriptors and save them in memory, accordingly.
>> -  //
>> -  // Note also that each descriptor will be aligned on a block size
>(BlockSize)
>> -  // boundary, so we need to read one block at a time.
>> +  // Allocate buffer for reading disk blocks
>>    //
>> -  BlockSize    = BlockIo->Media->BlockSize;
>> -  ExtentAd     = &AnchorPoint->MainVolumeDescriptorSequenceExtent;
>> -  StartingLsn  = (UINT64)ExtentAd->ExtentLocation;
>> -  EndingLsn    = StartingLsn + DivU64x32 (
>> -                                     (UINT64)ExtentAd->ExtentLength,
>> -                                     BlockSize
>> -                                     );
>> -
>> -  Volume->LogicalVolDescs =
>> -    (UDF_LOGICAL_VOLUME_DESCRIPTOR **)AllocateZeroPool (ExtentAd-
>> >ExtentLength);
>> -  if (Volume->LogicalVolDescs == NULL) {
>> -    return EFI_OUT_OF_RESOURCES;
>> -  }
>> -
>> -  Volume->PartitionDescs =
>> -    (UDF_PARTITION_DESCRIPTOR **)AllocateZeroPool (ExtentAd-
>> >ExtentLength);
>> -  if (Volume->PartitionDescs == NULL) {
>> -    Status = EFI_OUT_OF_RESOURCES;
>> -    goto Error_Alloc_Pds;
>> -  }
>> -
>> -  Buffer = AllocateZeroPool (BlockSize);
>> +  Buffer = AllocateZeroPool ((UINTN)BlockSize);
>>    if (Buffer == NULL) {
>> -    Status = EFI_OUT_OF_RESOURCES;
>> -    goto Error_Alloc_Buf;
>> +    return EFI_OUT_OF_RESOURCES;
>>    }
>> 
>> -  Volume->LogicalVolDescsNo  = 0;
>> -  Volume->PartitionDescsNo   = 0;
>> -
>> -  while (StartingLsn <= EndingLsn) {
>> -    Status = DiskIo->ReadDisk (
>> -      DiskIo,
>> +  //
>> +  // The logical partition created by Partition driver is relative
>to the main
>> +  // VDS extent location, so we start the Main Volume Descriptor
>Sequence at
>> +  // LBA 0.
>> +  //
>> +  // We don't need to check again if we have valid Volume
>Descriptors here
>> since
>> +  // Partition driver already did.
>> +  //
>> +  SeqStartBlock = 0;
>> +  SeqEndBlock = SeqStartBlock + DivU64x32
>((UINT64)ExtentAd->ExtentLength,
>> +                                           BlockSize);
>> +  StopSequence = FALSE;
>> +  for (; SeqStartBlock < SeqEndBlock && !StopSequence;
>SeqStartBlock++) {
>> +    //
>> +    // Read disk block
>> +    //
>> +    Status = BlockIo->ReadBlocks (
>> +      BlockIo,
>>        BlockIo->Media->MediaId,
>> -      MultU64x32 (StartingLsn, BlockSize),
>> +      SeqStartBlock,
>>        BlockSize,
>>        Buffer
>>        );
>>      if (EFI_ERROR (Status)) {
>> -      goto Error_Read_Disk_Blk;
>> +      goto Out_Free;
>>      }
>> 
>> -    if (IS_TD (Buffer)) {
>> +    DescriptorTag = Buffer;
>> +
>> +    switch (UDF_TAG_ID (DescriptorTag)) {
>> +    case UdfPartitionDescriptor:
>>        //
>> -      // Found a Terminating Descriptor. Stop the sequence then.
>> +      // Save Partition Descriptor
>>        //
>> +      CopyMem (&Volume->PartitionDesc, Buffer, sizeof (Volume-
>> >PartitionDesc));
>>        break;
>> -    }
>> 
>> -    if (IS_LVD (Buffer)) {
>> +    case UdfLogicalVolumeDescriptor:
>>        //
>> -      // Found a Logical Volume Descriptor.
>> +      // Save Logical Volume Descriptor
>>        //
>> -      LogicalVolDesc =
>> -        (UDF_LOGICAL_VOLUME_DESCRIPTOR *)
>> -        AllocateZeroPool (sizeof (UDF_LOGICAL_VOLUME_DESCRIPTOR));
>> -      if (LogicalVolDesc == NULL) {
>> -        Status = EFI_OUT_OF_RESOURCES;
>> -        goto Error_Alloc_Lvd;
>> -      }
>> +      CopyMem (&Volume->LogicalVolDesc, Buffer, sizeof (Volume-
>> >LogicalVolDesc));
>> +      break;
>> 
>> -      CopyMem ((VOID *)LogicalVolDesc, Buffer,
>> -               sizeof (UDF_LOGICAL_VOLUME_DESCRIPTOR));
>> -      Volume->LogicalVolDescs[Volume->LogicalVolDescsNo++] =
>> LogicalVolDesc;
>> -    } else if (IS_PD (Buffer)) {
>> -      //
>> -      // Found a Partition Descriptor.
>> -      //
>> -      PartitionDesc =
>> -        (UDF_PARTITION_DESCRIPTOR *)
>> -        AllocateZeroPool (sizeof (UDF_PARTITION_DESCRIPTOR));
>> -      if (PartitionDesc == NULL) {
>> -        Status = EFI_OUT_OF_RESOURCES;
>> -        goto Error_Alloc_Pd;
>> -      }
>> +    case UdfTerminatingDescriptor:
>> +      StopSequence = TRUE;
>> +      break;
>> 
>> -      CopyMem ((VOID *)PartitionDesc, Buffer,
>> -               sizeof (UDF_PARTITION_DESCRIPTOR));
>> -      Volume->PartitionDescs[Volume->PartitionDescsNo++] =
>PartitionDesc;
>> +    default:
>> +      ;
>>      }
>> -
>> -    StartingLsn++;
>>    }
>> 
>>    //
>> -  // When an UDF volume (revision 2.00 or higher) contains a File
>Entry rather
>> -  // than an Extended File Entry (which is not recommended as per
>spec), we
>> need
>> -  // to make sure the size of a FE will be _at least_ 2048
>> -  // (UDF_LOGICAL_SECTOR_SIZE) bytes long to keep backward
>compatibility.
>> +  // Determine FE (File Entry) size
>>    //
>> -  LogicalBlockSize = LV_BLOCK_SIZE (Volume, UDF_DEFAULT_LV_NUM);
>> +  LogicalBlockSize = Volume->LogicalVolDesc.LogicalBlockSize;
>>    if (LogicalBlockSize >= UDF_LOGICAL_SECTOR_SIZE) {
>> -    Volume->FileEntrySize = LogicalBlockSize;
>> +    Volume->FileEntrySize = (UINTN)LogicalBlockSize;
>>    } else {
>>      Volume->FileEntrySize = UDF_LOGICAL_SECTOR_SIZE;
>>    }
>> 
>> -  FreePool (Buffer);
>> +  Status = EFI_SUCCESS;
>> 
>> -  return EFI_SUCCESS;
>> -
>> -Error_Alloc_Pd:
>> -Error_Alloc_Lvd:
>> -  for (Index = 0; Index < Volume->PartitionDescsNo; Index++) {
>> -    FreePool ((VOID *)Volume->PartitionDescs[Index]);
>> -  }
>> -
>> -  for (Index = 0; Index < Volume->LogicalVolDescsNo; Index++) {
>> -    FreePool ((VOID *)Volume->LogicalVolDescs[Index]);
>> -  }
>> -
>> -Error_Read_Disk_Blk:
>> +Out_Free:
>> +  //
>> +  // Free block read buffer
>> +  //
>>    FreePool (Buffer);
>> 
>> -Error_Alloc_Buf:
>> -  FreePool ((VOID *)Volume->PartitionDescs);
>> -  Volume->PartitionDescs = NULL;
>> -
>> -Error_Alloc_Pds:
>> -  FreePool ((VOID *)Volume->LogicalVolDescs);
>> -  Volume->LogicalVolDescs = NULL;
>> -
>>    return Status;
>>  }
>> 
>> @@ -262,48 +216,53 @@ GetPdFromLongAd (
>>    )
>>  {
>>    UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;
>> -  UINTN                          Index;
>> -  UDF_PARTITION_DESCRIPTOR       *PartitionDesc;
>>    UINT16                         PartitionNum;
>> 
>> -  LogicalVolDesc = Volume->LogicalVolDescs[UDF_DEFAULT_LV_NUM];
>> +  LogicalVolDesc = &Volume->LogicalVolDesc;
>> 
>> -  switch (LV_UDF_REVISION (LogicalVolDesc)) {
>> +  switch (UDF_LVD_REVISION (LogicalVolDesc)) {
>>    case 0x0102:
>> +  case 0x0150:
>> +  case 0x0200:
>> +  case 0x0201:
>> +  case 0x0250:
>> +  case 0x0260:
>>      //
>> -    // As per UDF 1.02 specification:
>> +    // UDF 1.02 specification:
>>      //
>>      // There shall be exactly one prevailing Logical Volume
>Descriptor recorded
>>      // per Volume Set. The Partition Maps field shall contain only
>Type 1
>>      // Partition Maps.
>>      //
>> -    PartitionNum = *(UINT16
>*)((UINTN)&LogicalVolDesc->PartitionMaps[4]);
>> -    break;
>> -  case 0x0150:
>> +    // UDF 1.50 through 2.60 specs say:
>>      //
>> -    // Ensure Type 1 Partition map. Other types aren't supported in
>this
>> -    // implementation.
>> +    // For the purpose of interchange partition maps shall be
>limited to
>> +    // Partition Map type 1, except type 2 maps as described in the
>document.
>> +    //
>> +    // NOTE: Only one Type 1 (Physical) Partition is supported. It
>has been
>> +    // checked already in Partition driver for existence of a single
>Type 1
>> +    // Partition map, so we don't have to double check here.
>> +    //
>> +    // Partition reference number can also be retrieved from
>> +    // LongAd->ExtentLocation.PartitionReferenceNumber, however the
>spec
>> says
>> +    // it may be 0, so let's not rely on it.
>>      //
>> -    if (LogicalVolDesc->PartitionMaps[0] != 1 ||
>> -        LogicalVolDesc->PartitionMaps[1] != 6) {
>> -      return NULL;
>> -    }
>>      PartitionNum = *(UINT16
>*)((UINTN)&LogicalVolDesc->PartitionMaps[4]);
>>      break;
>> -  case 0x0260:
>> +
>> +  default:
>>      //
>> -    // Fall through.
>> +    // Unsupported UDF revision
>>      //
>> -  default:
>> -    PartitionNum = LongAd->ExtentLocation.PartitionReferenceNumber;
>> -    break;
>> +    return NULL;
>>    }
>> 
>> -  for (Index = 0; Index < Volume->PartitionDescsNo; Index++) {
>> -    PartitionDesc = Volume->PartitionDescs[Index];
>> -    if (PartitionDesc->PartitionNumber == PartitionNum) {
>> -      return PartitionDesc;
>> -    }
>> +  //
>> +  // Check if partition number matches Partition Descriptor found in
>Main
>> Volume
>> +  // Descriptor Sequence.
>> +  //
>> +  if (Volume->PartitionDesc.PartitionNumber == PartitionNum) {
>> +    return &Volume->PartitionDesc;
>>    }
>> 
>>    return NULL;
>> @@ -329,13 +288,15 @@ GetLongAdLsn (
>>    PartitionDesc = GetPdFromLongAd (Volume, LongAd);
>>    ASSERT (PartitionDesc != NULL);
>> 
>> -  return (UINT64)PartitionDesc->PartitionStartingLocation +
>> -                 LongAd->ExtentLocation.LogicalBlockNumber;
>> +  return (UINT64)PartitionDesc->PartitionStartingLocation -
>> +    Volume->MainVdsStartLocation +
>> +    LongAd->ExtentLocation.LogicalBlockNumber;
>>  }
>> 
>>  /**
>>    Return logical sector number of a given Short Allocation
>Descriptor.
>> 
>> +  @param[in]  Volume              Volume pointer.
>>    @param[in]  PartitionDesc       Partition Descriptor pointer.
>>    @param[in]  ShortAd             Short Allocation Descriptor
>pointer.
>> 
>> @@ -344,14 +305,13 @@ GetLongAdLsn (
>>  **/
>>  UINT64
>>  GetShortAdLsn (
>> +  IN UDF_VOLUME_INFO                  *Volume,
>>    IN UDF_PARTITION_DESCRIPTOR         *PartitionDesc,
>>    IN UDF_SHORT_ALLOCATION_DESCRIPTOR  *ShortAd
>>    )
>>  {
>> -  ASSERT (PartitionDesc != NULL);
>> -
>> -  return (UINT64)PartitionDesc->PartitionStartingLocation +
>> -    ShortAd->ExtentPosition;
>> +  return (UINT64)PartitionDesc->PartitionStartingLocation -
>> +    Volume->MainVdsStartLocation + ShortAd->ExtentPos

-- 
Sent from my Android device with K-9 Mail. Please excuse my brevity.
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Re: [edk2] [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix creation of UDF logical partition
Posted by Zeng, Star 7 years, 3 months ago
Does it have functional impact?

Thanks,
Star
-----Original Message-----
From: Paulo Alcantara [mailto:pcacjr@zytor.com] 
Sent: Thursday, September 21, 2017 9:29 PM
To: Wu, Hao A <hao.a.wu@intel.com>; edk2-devel@lists.01.org
Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Laszlo Ersek <lersek@redhat.com>; Dong, Eric <eric.dong@intel.com>; Zeng, Star <star.zeng@intel.com>
Subject: RE: [edk2] [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix creation of UDF logical partition



On September 21, 2017 9:44:10 AM GMT-03:00, "Wu, Hao A" <hao.a.wu@intel.com> wrote:
>One small comment, within function PartitionInstallUdfChildHandles():
>
>  ...
>  //
>  // Install partition child handle for UDF file system
>  //
>  Status = PartitionInstallChildHandle (
>    ...
>    );
>if (!EFI_ERROR (Status)) {  <----- Is this a typo? "if (EFI_ERROR
>(Status)) {"  
>    Status = EFI_NOT_FOUND;
>  }

Yes, it is. Good catch! Could you please fix that for me by removing the if condition? Otherwise I can send a v4 later with that.

Thanks!
Paulo

>  
>
>Best Regards,
>Hao Wu
>
>
>> -----Original Message-----
>> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf
>Of Paulo
>> Alcantara
>> Sent: Thursday, September 21, 2017 2:16 AM
>> To: edk2-devel@lists.01.org
>> Cc: Ni, Ruiyu; Laszlo Ersek; Dong, Eric; Zeng, Star
>> Subject: [edk2] [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix
>creation of
>> UDF logical partition
>> 
>> Do not reserve entire block device size for an UDF file system - 
>> instead, reserve the appropriate space (UDF logical volume space) for 
>> it.
>> 
>> Additionally, only create a logical partition for UDF logical volumes 
>> that are currently supported by EDK2 UDF file system implementation.
>For
>> instance, an UDF volume with a single LVD and a single Physical (Type
>1)
>> Partition will be supported.
>> 
>> Cc: Eric Dong <eric.dong@intel.com>
>> Cc: Ruiyu Ni <ruiyu.ni@intel.com>
>> Cc: Star Zeng <star.zeng@intel.com>
>> Cc: Laszlo Ersek <lersek@redhat.com>
>> Reported-by: Ruiyu Ni <ruiyu.ni@intel.com>
>> Contributed-under: TianoCore Contribution Agreement 1.1
>> Signed-off-by: Paulo Alcantara <pcacjr@zytor.com>
>> ---
>>  MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c            | 363
>++++++++++--
>>  MdeModulePkg/Universal/Disk/UdfDxe/File.c                 |  16 +-
>>  MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c | 627
>> ++++++++------------
>>  MdeModulePkg/Universal/Disk/UdfDxe/Udf.c                  |   7 -
>>  MdeModulePkg/Universal/Disk/UdfDxe/Udf.h                  | 158
>++---
>>  5 files changed, 606 insertions(+), 565 deletions(-)
>> 
>> diff --git a/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
>> b/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
>> index 609f56cef6..572ba7a81a 100644
>> --- a/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
>> +++ b/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
>> @@ -64,11 +64,12 @@ FindAnchorVolumeDescriptorPointer (
>>    OUT  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint
>>    )
>>  {
>> -  EFI_STATUS  Status;
>> -  UINT32      BlockSize;
>> -  EFI_LBA     EndLBA;
>> -  EFI_LBA     DescriptorLBAs[4];
>> -  UINTN       Index;
>> +  EFI_STATUS          Status;
>> +  UINT32              BlockSize;
>> +  EFI_LBA             EndLBA;
>> +  EFI_LBA             DescriptorLBAs[4];
>> +  UINTN               Index;
>> +  UDF_DESCRIPTOR_TAG  *DescriptorTag;
>> 
>>    BlockSize = BlockIo->Media->BlockSize;
>>    EndLBA = BlockIo->Media->LastBlock; @@ -88,10 +89,13 @@ 
>> FindAnchorVolumeDescriptorPointer (
>>      if (EFI_ERROR (Status)) {
>>        return Status;
>>      }
>> +
>> +    DescriptorTag = &AnchorPoint->DescriptorTag;
>> +
>>      //
>>      // Check if read LBA has a valid AVDP descriptor.
>>      //
>> -    if (IS_AVDP (AnchorPoint)) {
>> +    if (DescriptorTag->TagIdentifier ==
>UdfAnchorVolumeDescriptorPointer) {
>>        return EFI_SUCCESS;
>>      }
>>    }
>> @@ -102,23 +106,18 @@ FindAnchorVolumeDescriptorPointer (  }
>> 
>>  /**
>> -  Check if block device supports a valid UDF file system as
>specified by OSTA
>> -  Universal Disk Format Specification 2.60.
>> +  Find UDF volume identifiers in a Volume Recognition Sequence.
>> 
>> -  @param[in]   BlockIo  BlockIo interface.
>> -  @param[in]   DiskIo   DiskIo interface.
>> +  @param[in]  BlockIo             BlockIo interface.
>> +  @param[in]  DiskIo              DiskIo interface.
>> 
>> -  @retval EFI_SUCCESS          UDF file system found.
>> -  @retval EFI_UNSUPPORTED      UDF file system not found.
>> -  @retval EFI_NO_MEDIA         The device has no media.
>> -  @retval EFI_DEVICE_ERROR     The device reported an error.
>> -  @retval EFI_VOLUME_CORRUPTED The file system structures are
>corrupted.
>> -  @retval EFI_OUT_OF_RESOURCES The scan was not successful due to
>lack of
>> -                               resources.
>> +  @retval EFI_SUCCESS             UDF volume identifiers were found.
>> +  @retval EFI_NOT_FOUND           UDF volume identifiers were not
>found.
>> +  @retval other                   Failed to perform disk I/O.
>> 
>>  **/
>>  EFI_STATUS
>> -SupportUdfFileSystem (
>> +FindUdfVolumeIdentifiers (
>>    IN EFI_BLOCK_IO_PROTOCOL  *BlockIo,
>>    IN EFI_DISK_IO_PROTOCOL   *DiskIo
>>    )
>> @@ -128,7 +127,6 @@ SupportUdfFileSystem (
>>    UINT64                                EndDiskOffset;
>>    CDROM_VOLUME_DESCRIPTOR               VolDescriptor;
>>    CDROM_VOLUME_DESCRIPTOR               TerminatingVolDescriptor;
>> -  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  AnchorPoint;
>> 
>>    ZeroMem ((VOID *)&TerminatingVolDescriptor, sizeof 
>> (CDROM_VOLUME_DESCRIPTOR));
>> 
>> @@ -167,7 +165,7 @@ SupportUdfFileSystem (
>>          (CompareMem ((VOID *)&VolDescriptor,
>>                       (VOID *)&TerminatingVolDescriptor,
>>                       sizeof (CDROM_VOLUME_DESCRIPTOR)) == 0)) {
>> -      return EFI_UNSUPPORTED;
>> +      return EFI_NOT_FOUND;
>>      }
>>    }
>> 
>> @@ -176,7 +174,7 @@ SupportUdfFileSystem (
>>    //
>>    Offset += UDF_LOGICAL_SECTOR_SIZE;
>>    if (Offset >= EndDiskOffset) {
>> -    return EFI_UNSUPPORTED;
>> +    return EFI_NOT_FOUND;
>>    }
>> 
>>    Status = DiskIo->ReadDisk (
>> @@ -196,7 +194,7 @@ SupportUdfFileSystem (
>>        (CompareMem ((VOID *)VolDescriptor.Unknown.Id,
>>                     (VOID *)UDF_NSR3_IDENTIFIER,
>>                     sizeof (VolDescriptor.Unknown.Id)) != 0)) {
>> -    return EFI_UNSUPPORTED;
>> +    return EFI_NOT_FOUND;
>>    }
>> 
>>    //
>> @@ -204,7 +202,7 @@ SupportUdfFileSystem (
>>    //
>>    Offset += UDF_LOGICAL_SECTOR_SIZE;
>>    if (Offset >= EndDiskOffset) {
>> -    return EFI_UNSUPPORTED;
>> +    return EFI_NOT_FOUND;
>>    }
>> 
>>    Status = DiskIo->ReadDisk (
>> @@ -221,15 +219,291 @@ SupportUdfFileSystem (
>>    if (CompareMem ((VOID *)VolDescriptor.Unknown.Id,
>>                    (VOID *)UDF_TEA_IDENTIFIER,
>>                    sizeof (VolDescriptor.Unknown.Id)) != 0) {
>> -    return EFI_UNSUPPORTED;
>> +    return EFI_NOT_FOUND;
>> +  }
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +/**
>> +  Check if Logical Volume Descriptor is supported by current EDK2
>UDF file
>> +  system implementation.
>> +
>> +  @param[in]  LogicalVolDesc  Logical Volume Descriptor pointer.
>> +
>> +  @retval TRUE                Logical Volume Descriptor is
>supported.
>> +  @retval FALSE               Logical Volume Descriptor is not
>supported.
>> +
>> +**/
>> +BOOLEAN
>> +IsLogicalVolumeDescriptorSupported (
>> +  UDF_LOGICAL_VOLUME_DESCRIPTOR *LogicalVolDesc
>> +  )
>> +{
>> +  //
>> +  // Check for a valid UDF revision range
>> +  //
>> +  switch (UDF_LVD_REVISION (LogicalVolDesc)) {
>> +  case 0x0102:
>> +  case 0x0150:
>> +  case 0x0200:
>> +  case 0x0201:
>> +  case 0x0250:
>> +  case 0x0260:
>> +    break;
>> +  default:
>> +    return FALSE;
>> +  }
>> +
>> +  //
>> +  // Check for a single Partition Map  //  if 
>> + (LogicalVolDesc->NumberOfPartitionMaps > 1) {
>> +    return FALSE;
>> +  }
>> +  //
>> +  // UDF 1.02 revision supports only Type 1 (Physical) partitions,
>but
>> +  // let's check it any way.
>> +  //
>> +  // PartitionMap[0] -> type
>> +  // PartitionMap[1] -> length (in bytes)  //  if 
>> + (LogicalVolDesc->PartitionMaps[0] != 1 ||
>> +      LogicalVolDesc->PartitionMaps[1] != 6) {
>> +    return FALSE;
>> +  }
>> +
>> +  return TRUE;
>> +}
>> +
>> +/**
>> +  Find UDF logical volume location and whether it is supported by
>current EDK2
>> +  UDF file system implementation.
>> +
>> +  @param[in]  BlockIo             BlockIo interface.
>> +  @param[in]  DiskIo              DiskIo interface.
>> +  @param[in]  AnchorPoint         Anchor volume descriptor pointer.
>> +  @param[out] MainVdsStartBlock   Main VDS starting block number.
>> +  @param[out] MainVdsEndBlock     Main VDS ending block number.
>> +
>> +  @retval EFI_SUCCESS             UDF logical volume was found.
>> +  @retval EFI_VOLUME_CORRUPTED    UDF file system structures are
>> corrupted.
>> +  @retval EFI_UNSUPPORTED         UDF logical volume is not
>supported.
>> +  @retval other                   Failed to perform disk I/O.
>> +
>> +**/
>> +EFI_STATUS
>> +FindLogicalVolumeLocation (
>> +  IN   EFI_BLOCK_IO_PROTOCOL                 *BlockIo,
>> +  IN   EFI_DISK_IO_PROTOCOL                  *DiskIo,
>> +  IN   UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint,
>> +  OUT  UINT64                                *MainVdsStartBlock,
>> +  OUT  UINT64                                *MainVdsEndBlock
>> +  )
>> +{
>> +  EFI_STATUS                     Status;
>> +  UINT32                         BlockSize;
>> +  EFI_LBA                        LastBlock;
>> +  UDF_EXTENT_AD                  *ExtentAd;
>> +  UINT64                         SeqBlocksNum;
>> +  UINT64                         SeqStartBlock;
>> +  UINT64                         GuardMainVdsStartBlock;
>> +  VOID                           *Buffer;
>> +  UINT64                         SeqEndBlock;
>> +  BOOLEAN                        StopSequence;
>> +  UINTN                          LvdsCount;
>> +  UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;
>> +  UDF_DESCRIPTOR_TAG             *DescriptorTag;
>> +
>> +  BlockSize = BlockIo->Media->BlockSize;  LastBlock = 
>> + BlockIo->Media->LastBlock;  ExtentAd = 
>> + &AnchorPoint->MainVolumeDescriptorSequenceExtent;
>> +
>> +  //
>> +  // UDF 2.60, 2.2.3.1 struct MainVolumeDescriptorSequenceExtent
>> +  //
>> +  // The Main Volume Descriptor Sequence Extent shall have a minimum
>length
>> of
>> +  // 16 logical sectors.
>> +  //
>> +  // Also make sure it does not exceed maximum number of blocks in
>the disk.
>> +  //
>> +  SeqBlocksNum = DivU64x32 ((UINT64)ExtentAd->ExtentLength,
>BlockSize);
>> +  if (SeqBlocksNum < 16 || (EFI_LBA)SeqBlocksNum > LastBlock + 1) {
>> +    return EFI_VOLUME_CORRUPTED;
>> +  }
>> +
>> +  //
>> +  // Check for valid Volume Descriptor Sequence starting block
>number
>> +  //
>> +  SeqStartBlock = (UINT64)ExtentAd->ExtentLocation;  if 
>> + (SeqStartBlock > LastBlock ||
>> +      SeqStartBlock + SeqBlocksNum - 1 > LastBlock) {
>> +    return EFI_VOLUME_CORRUPTED;
>>    }
>> 
>> +  GuardMainVdsStartBlock = SeqStartBlock;
>> +
>> +  //
>> +  // Allocate buffer for reading disk blocks  //  Buffer = 
>> + AllocateZeroPool ((UINTN)BlockSize);  if (Buffer == NULL) {
>> +    return EFI_OUT_OF_RESOURCES;
>> +  }
>> +
>> +  SeqEndBlock = SeqStartBlock + SeqBlocksNum;  StopSequence = FALSE;  
>> + LvdsCount = 0;  Status = EFI_VOLUME_CORRUPTED;  //  // Start Main 
>> + Volume Descriptor Sequence  //  for (; SeqStartBlock < SeqEndBlock 
>> + && !StopSequence;
>SeqStartBlock++) {
>> +    //
>> +    // Read disk block
>> +    //
>> +    Status = BlockIo->ReadBlocks (
>> +      BlockIo,
>> +      BlockIo->Media->MediaId,
>> +      SeqStartBlock,
>> +      BlockSize,
>> +      Buffer
>> +      );
>> +    if (EFI_ERROR (Status)) {
>> +      goto Out_Free;
>> +    }
>> +
>> +    DescriptorTag = Buffer;
>> +
>> +    //
>> +    // ECMA 167, 8.4.1 Contents of a Volume Descriptor Sequence
>> +    //
>> +    // - A Volume Descriptor Sequence shall contain one or more
>Primary
>> Volume
>> +    //   Descriptors.
>> +    // - A Volume Descriptor Sequence shall contain zero or more
>> Implementation
>> +    //   Use Volume Descriptors.
>> +    // - A Volume Descriptor Sequence shall contain zero or more
>Partition
>> +    //   Descriptors.
>> +    // - A Volume Descriptor Sequence shall contain zero or more
>Logical
>> Volume
>> +    //   Descriptors.
>> +    // - A Volume Descriptor Sequence shall contain zero or more
>Unallocated
>> +    //   Space Descriptors.
>> +    //
>> +    switch (UDF_TAG_ID (DescriptorTag)) {
>> +    case UdfPrimaryVolumeDescriptor:
>> +    case UdfImplemenationUseVolumeDescriptor:
>> +    case UdfPartitionDescriptor:
>> +    case UdfUnallocatedSpaceDescriptor:
>> +      break;
>> +
>> +    case UdfLogicalVolumeDescriptor:
>> +      LogicalVolDesc = Buffer;
>> +
>> +      //
>> +      // Check for existence of a single LVD and whether it is
>supported by
>> +      // current EDK2 UDF file system implementation.
>> +      //
>> +      if (++LvdsCount > 1 ||
>> +          !IsLogicalVolumeDescriptorSupported (LogicalVolDesc)) {
>> +        Status = EFI_UNSUPPORTED;
>> +        StopSequence = TRUE;
>> +      }
>> +
>> +      break;
>> +
>> +    case UdfTerminatingDescriptor:
>> +      //
>> +      // Stop the sequence when we find a Terminating Descriptor
>> +      // (aka Unallocated Sector), se we don't have to walk all the
>unallocated
>> +      // area unnecessarily.
>> +      //
>> +      StopSequence = TRUE;
>> +      break;
>> +
>> +    default:
>> +      //
>> +      // An invalid Volume Descriptor has been found in the sequece.
>Volume is
>> +      // corrupted.
>> +      //
>> +      Status = EFI_VOLUME_CORRUPTED;
>> +      goto Out_Free;
>> +    }
>> +  }
>> +
>> +  //
>> +  // Check if LVD was found
>> +  //
>> +  if (!EFI_ERROR (Status) && LvdsCount == 1) {
>> +    *MainVdsStartBlock = GuardMainVdsStartBlock;
>> +    //
>> +    // We do not need to read either LVD or PD descriptors to know
>the last
>> +    // valid block in the found UDF file system. It's already
>LastBlock.
>> +    //
>> +    *MainVdsEndBlock = LastBlock;
>> +
>> +    Status = EFI_SUCCESS;
>> +  }
>> +
>> +Out_Free:
>> +  //
>> +  // Free block read buffer
>> +  //
>> +  FreePool (Buffer);
>> +
>> +  return Status;
>> +}
>> +
>> +/**
>> +  Find a supported UDF file system in block device.
>> +
>> +  @param[in]  BlockIo             BlockIo interface.
>> +  @param[in]  DiskIo              DiskIo interface.
>> +  @param[out] StartingLBA         UDF file system starting LBA.
>> +  @param[out] EndingLBA           UDF file system starting LBA.
>> +
>> +  @retval EFI_SUCCESS             UDF file system was found.
>> +  @retval other                   UDF file system was not found.
>> +
>> +**/
>> +EFI_STATUS
>> +FindUdfFileSystem (
>> +  IN EFI_BLOCK_IO_PROTOCOL  *BlockIo,
>> +  IN EFI_DISK_IO_PROTOCOL   *DiskIo,
>> +  OUT EFI_LBA               *StartingLBA,
>> +  OUT EFI_LBA               *EndingLBA
>> +  )
>> +{
>> +  EFI_STATUS Status;
>> +  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  AnchorPoint;
>> +
>> +  //
>> +  // Find UDF volume identifiers
>> +  //
>> +  Status = FindUdfVolumeIdentifiers (BlockIo, DiskIo);  if 
>> + (EFI_ERROR (Status)) {
>> +    return Status;
>> +  }
>> +
>> +  //
>> +  // Find Anchor Volume Descriptor Pointer  //
>>    Status = FindAnchorVolumeDescriptorPointer (BlockIo, DiskIo,
>&AnchorPoint);
>>    if (EFI_ERROR (Status)) {
>> -    return EFI_UNSUPPORTED;
>> +    return Status;
>>    }
>> 
>> -  return EFI_SUCCESS;
>> +  //
>> +  // Find Logical Volume location
>> +  //
>> +  Status = FindLogicalVolumeLocation (
>> +    BlockIo,
>> +    DiskIo,
>> +    &AnchorPoint,
>> +    (UINT64 *)StartingLBA,
>> +    (UINT64 *)EndingLBA
>> +    );
>> +
>> +  return Status;
>>  }
>> 
>>  /**
>> @@ -263,9 +537,9 @@ PartitionInstallUdfChildHandles (
>>    UINT32                       RemainderByMediaBlockSize;
>>    EFI_STATUS                   Status;
>>    EFI_BLOCK_IO_MEDIA           *Media;
>> -  EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode;
>> -  EFI_GUID                     *VendorDefinedGuid;
>>    EFI_PARTITION_INFO_PROTOCOL  PartitionInfo;
>> +  EFI_LBA                      StartingLBA;
>> +  EFI_LBA                      EndingLBA;
>> 
>>    Media = BlockIo->Media;
>> 
>> @@ -281,35 +555,10 @@ PartitionInstallUdfChildHandles (
>>      return EFI_NOT_FOUND;
>>    }
>> 
>> -  DevicePathNode = DevicePath;
>> -  while (!IsDevicePathEnd (DevicePathNode)) {
>> -    //
>> -    // Do not allow checking for UDF file systems in CDROM "El
>Torito"
>> -    // partitions, and skip duplicate installation of UDF file
>system child
>> -    // nodes.
>> -    //
>> -    if (DevicePathType (DevicePathNode) == MEDIA_DEVICE_PATH) {
>> -      if (DevicePathSubType (DevicePathNode) == MEDIA_CDROM_DP) {
>> -        return EFI_NOT_FOUND;
>> -      }
>> -      if (DevicePathSubType (DevicePathNode) == MEDIA_VENDOR_DP) {
>> -        VendorDefinedGuid = (EFI_GUID *)((UINTN)DevicePathNode +
>> -                                         OFFSET_OF
>(VENDOR_DEVICE_PATH, Guid));
>> -        if (CompareGuid (VendorDefinedGuid, &gUdfDevPathGuid)) {
>> -          return EFI_NOT_FOUND;
>> -        }
>> -      }
>> -    }
>> -    //
>> -    // Try next device path node
>> -    //
>> -    DevicePathNode = NextDevicePathNode (DevicePathNode);
>> -  }
>> -
>>    //
>> -  // Check if block device supports an UDF file system
>> +  // Search for an UDF file system on block device
>>    //
>> -  Status = SupportUdfFileSystem (BlockIo, DiskIo);
>> +  Status = FindUdfFileSystem (BlockIo, DiskIo, &StartingLBA,
>&EndingLBA);
>>    if (EFI_ERROR (Status)) {
>>      return EFI_NOT_FOUND;
>>    }
>> @@ -334,8 +583,8 @@ PartitionInstallUdfChildHandles (
>>      DevicePath,
>>      (EFI_DEVICE_PATH_PROTOCOL *)&gUdfDevicePath,
>>      &PartitionInfo,
>> -    0,
>> -    Media->LastBlock,
>> +    StartingLBA,
>> +    EndingLBA,
>>      Media->BlockSize
>>      );
>>    if (!EFI_ERROR (Status)) {
>> diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/File.c
>> b/MdeModulePkg/Universal/Disk/UdfDxe/File.c
>> index 625f2c5637..6f07bf2066 100644
>> --- a/MdeModulePkg/Universal/Disk/UdfDxe/File.c
>> +++ b/MdeModulePkg/Universal/Disk/UdfDxe/File.c
>> @@ -131,7 +131,6 @@ Error_Alloc_Priv_File_Data:
>>    CleanupFileInformation (&PrivFsData->Root);
>> 
>>  Error_Find_Root_Dir:
>> -  CleanupVolumeInformation (&PrivFsData->Volume);
>> 
>>  Error_Read_Udf_Volume:
>>  Error_Invalid_Params:
>> @@ -429,7 +428,7 @@ UdfRead (
>>      }
>>      ASSERT (NewFileEntryData != NULL);
>> 
>> -    if (IS_FE_SYMLINK (NewFileEntryData)) {
>> +    if (FE_ICB_FILE_TYPE (NewFileEntryData) == UdfFileEntrySymlink)
>{
>>        Status = ResolveSymlink (
>>          BlockIo,
>>          DiskIo,
>> @@ -529,7 +528,6 @@ UdfClose (
>>    EFI_TPL                     OldTpl;
>>    EFI_STATUS                  Status;
>>    PRIVATE_UDF_FILE_DATA       *PrivFileData;
>> -  PRIVATE_UDF_SIMPLE_FS_DATA  *PrivFsData;
>> 
>>    OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
>> 
>> @@ -542,8 +540,6 @@ UdfClose (
>> 
>>    PrivFileData = PRIVATE_UDF_FILE_DATA_FROM_THIS (This);
>> 
>> -  PrivFsData = PRIVATE_UDF_SIMPLE_FS_DATA_FROM_THIS (PrivFileData-
>> >SimpleFs);
>> -
>>    if (!PrivFileData->IsRootDirectory) {
>>      CleanupFileInformation (&PrivFileData->File);
>> 
>> @@ -552,10 +548,6 @@ UdfClose (
>>      }
>>    }
>> 
>> -  if (--PrivFsData->OpenFiles == 0) {
>> -    CleanupVolumeInformation (&PrivFsData->Volume);
>> -  }
>> -
>>    FreePool ((VOID *)PrivFileData);
>> 
>>  Exit:
>> @@ -652,7 +644,7 @@ UdfGetPosition (
>>    // As per UEFI spec, if the file handle is a directory, then the
>current file
>>    // position has no meaning and the operation is not supported.
>>    //
>> -  if (IS_FID_DIRECTORY_FILE
>(&PrivFileData->File.FileIdentifierDesc)) {
>> +  if (IS_FID_DIRECTORY_FILE (PrivFileData->File.FileIdentifierDesc))
>{
>>      return  EFI_UNSUPPORTED;
>>    }
>> 
>> @@ -788,7 +780,7 @@ UdfGetInfo (
>>    } else if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid))
>{
>>      String = VolumeLabel;
>> 
>> -    FileSetDesc = PrivFsData->Volume.FileSetDescs[0];
>> +    FileSetDesc = &PrivFsData->Volume.FileSetDesc;
>> 
>>      OstaCompressed = &FileSetDesc->LogicalVolumeIdentifier[0];
>> 
>> @@ -847,7 +839,7 @@ UdfGetInfo (
>>      FileSystemInfo->Size        = FileSystemInfoLength;
>>      FileSystemInfo->ReadOnly    = TRUE;
>>      FileSystemInfo->BlockSize   =
>> -      LV_BLOCK_SIZE (&PrivFsData->Volume, UDF_DEFAULT_LV_NUM);
>> +      PrivFsData->Volume.LogicalVolDesc.LogicalBlockSize;
>>      FileSystemInfo->VolumeSize  = VolumeSize;
>>      FileSystemInfo->FreeSpace   = FreeSpaceSize;
>> 
>> diff --git
>a/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
>> b/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
>> index 5df267761f..62d817989f 100644
>> --- a/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
>> +++ b/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
>> @@ -38,11 +38,12 @@ FindAnchorVolumeDescriptorPointer (
>>    OUT  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint
>>    )
>>  {
>> -  EFI_STATUS  Status;
>> -  UINT32      BlockSize;
>> -  EFI_LBA     EndLBA;
>> -  EFI_LBA     DescriptorLBAs[4];
>> -  UINTN       Index;
>> +  EFI_STATUS          Status;
>> +  UINT32              BlockSize;
>> +  EFI_LBA             EndLBA;
>> +  EFI_LBA             DescriptorLBAs[4];
>> +  UINTN               Index;
>> +  UDF_DESCRIPTOR_TAG  *DescriptorTag;
>> 
>>    BlockSize = BlockIo->Media->BlockSize;
>>    EndLBA = BlockIo->Media->LastBlock; @@ -62,10 +63,13 @@ 
>> FindAnchorVolumeDescriptorPointer (
>>      if (EFI_ERROR (Status)) {
>>        return Status;
>>      }
>> +
>> +    DescriptorTag = &AnchorPoint->DescriptorTag;
>> +
>>      //
>>      // Check if read LBA has a valid AVDP descriptor.
>>      //
>> -    if (IS_AVDP (AnchorPoint)) {
>> +    if (DescriptorTag->TagIdentifier ==
>UdfAnchorVolumeDescriptorPointer) {
>>        return EFI_SUCCESS;
>>      }
>>    }
>> @@ -99,148 +103,98 @@ StartMainVolumeDescriptorSequence (
>>    OUT  UDF_VOLUME_INFO                       *Volume
>>    )
>>  {
>> -  EFI_STATUS                     Status;
>> -  UINT32                         BlockSize;
>> -  UDF_EXTENT_AD                  *ExtentAd;
>> -  UINT64                         StartingLsn;
>> -  UINT64                         EndingLsn;
>> -  VOID                           *Buffer;
>> -  UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;
>> -  UDF_PARTITION_DESCRIPTOR       *PartitionDesc;
>> -  UINTN                          Index;
>> -  UINT32                         LogicalBlockSize;
>> +  EFI_STATUS            Status;
>> +  UINT32                BlockSize;
>> +  UDF_EXTENT_AD         *ExtentAd;
>> +  EFI_LBA               SeqStartBlock;
>> +  EFI_LBA               SeqEndBlock;
>> +  BOOLEAN               StopSequence;
>> +  VOID                  *Buffer;
>> +  UDF_DESCRIPTOR_TAG    *DescriptorTag;
>> +  UINT32                LogicalBlockSize;
>> +
>> +  BlockSize = BlockIo->Media->BlockSize;  ExtentAd = 
>> + &AnchorPoint->MainVolumeDescriptorSequenceExtent;
>> 
>>    //
>> -  // We've already found an ADVP on the volume. It contains the
>extent
>> -  // (MainVolumeDescriptorSequenceExtent) where the Main Volume 
>> Descriptor
>> -  // Sequence starts. Therefore, we'll look for Logical Volume
>Descriptors and
>> -  // Partitions Descriptors and save them in memory, accordingly.
>> -  //
>> -  // Note also that each descriptor will be aligned on a block size
>(BlockSize)
>> -  // boundary, so we need to read one block at a time.
>> +  // Allocate buffer for reading disk blocks
>>    //
>> -  BlockSize    = BlockIo->Media->BlockSize;
>> -  ExtentAd     = &AnchorPoint->MainVolumeDescriptorSequenceExtent;
>> -  StartingLsn  = (UINT64)ExtentAd->ExtentLocation;
>> -  EndingLsn    = StartingLsn + DivU64x32 (
>> -                                     (UINT64)ExtentAd->ExtentLength,
>> -                                     BlockSize
>> -                                     );
>> -
>> -  Volume->LogicalVolDescs =
>> -    (UDF_LOGICAL_VOLUME_DESCRIPTOR **)AllocateZeroPool (ExtentAd-
>> >ExtentLength);
>> -  if (Volume->LogicalVolDescs == NULL) {
>> -    return EFI_OUT_OF_RESOURCES;
>> -  }
>> -
>> -  Volume->PartitionDescs =
>> -    (UDF_PARTITION_DESCRIPTOR **)AllocateZeroPool (ExtentAd-
>> >ExtentLength);
>> -  if (Volume->PartitionDescs == NULL) {
>> -    Status = EFI_OUT_OF_RESOURCES;
>> -    goto Error_Alloc_Pds;
>> -  }
>> -
>> -  Buffer = AllocateZeroPool (BlockSize);
>> +  Buffer = AllocateZeroPool ((UINTN)BlockSize);
>>    if (Buffer == NULL) {
>> -    Status = EFI_OUT_OF_RESOURCES;
>> -    goto Error_Alloc_Buf;
>> +    return EFI_OUT_OF_RESOURCES;
>>    }
>> 
>> -  Volume->LogicalVolDescsNo  = 0;
>> -  Volume->PartitionDescsNo   = 0;
>> -
>> -  while (StartingLsn <= EndingLsn) {
>> -    Status = DiskIo->ReadDisk (
>> -      DiskIo,
>> +  //
>> +  // The logical partition created by Partition driver is relative
>to the main
>> +  // VDS extent location, so we start the Main Volume Descriptor
>Sequence at
>> +  // LBA 0.
>> +  //
>> +  // We don't need to check again if we have valid Volume
>Descriptors here
>> since
>> +  // Partition driver already did.
>> +  //
>> +  SeqStartBlock = 0;
>> +  SeqEndBlock = SeqStartBlock + DivU64x32
>((UINT64)ExtentAd->ExtentLength,
>> +                                           BlockSize);  StopSequence 
>> + = FALSE;  for (; SeqStartBlock < SeqEndBlock && !StopSequence;
>SeqStartBlock++) {
>> +    //
>> +    // Read disk block
>> +    //
>> +    Status = BlockIo->ReadBlocks (
>> +      BlockIo,
>>        BlockIo->Media->MediaId,
>> -      MultU64x32 (StartingLsn, BlockSize),
>> +      SeqStartBlock,
>>        BlockSize,
>>        Buffer
>>        );
>>      if (EFI_ERROR (Status)) {
>> -      goto Error_Read_Disk_Blk;
>> +      goto Out_Free;
>>      }
>> 
>> -    if (IS_TD (Buffer)) {
>> +    DescriptorTag = Buffer;
>> +
>> +    switch (UDF_TAG_ID (DescriptorTag)) {
>> +    case UdfPartitionDescriptor:
>>        //
>> -      // Found a Terminating Descriptor. Stop the sequence then.
>> +      // Save Partition Descriptor
>>        //
>> +      CopyMem (&Volume->PartitionDesc, Buffer, sizeof (Volume-
>> >PartitionDesc));
>>        break;
>> -    }
>> 
>> -    if (IS_LVD (Buffer)) {
>> +    case UdfLogicalVolumeDescriptor:
>>        //
>> -      // Found a Logical Volume Descriptor.
>> +      // Save Logical Volume Descriptor
>>        //
>> -      LogicalVolDesc =
>> -        (UDF_LOGICAL_VOLUME_DESCRIPTOR *)
>> -        AllocateZeroPool (sizeof (UDF_LOGICAL_VOLUME_DESCRIPTOR));
>> -      if (LogicalVolDesc == NULL) {
>> -        Status = EFI_OUT_OF_RESOURCES;
>> -        goto Error_Alloc_Lvd;
>> -      }
>> +      CopyMem (&Volume->LogicalVolDesc, Buffer, sizeof (Volume-
>> >LogicalVolDesc));
>> +      break;
>> 
>> -      CopyMem ((VOID *)LogicalVolDesc, Buffer,
>> -               sizeof (UDF_LOGICAL_VOLUME_DESCRIPTOR));
>> -      Volume->LogicalVolDescs[Volume->LogicalVolDescsNo++] =
>> LogicalVolDesc;
>> -    } else if (IS_PD (Buffer)) {
>> -      //
>> -      // Found a Partition Descriptor.
>> -      //
>> -      PartitionDesc =
>> -        (UDF_PARTITION_DESCRIPTOR *)
>> -        AllocateZeroPool (sizeof (UDF_PARTITION_DESCRIPTOR));
>> -      if (PartitionDesc == NULL) {
>> -        Status = EFI_OUT_OF_RESOURCES;
>> -        goto Error_Alloc_Pd;
>> -      }
>> +    case UdfTerminatingDescriptor:
>> +      StopSequence = TRUE;
>> +      break;
>> 
>> -      CopyMem ((VOID *)PartitionDesc, Buffer,
>> -               sizeof (UDF_PARTITION_DESCRIPTOR));
>> -      Volume->PartitionDescs[Volume->PartitionDescsNo++] =
>PartitionDesc;
>> +    default:
>> +      ;
>>      }
>> -
>> -    StartingLsn++;
>>    }
>> 
>>    //
>> -  // When an UDF volume (revision 2.00 or higher) contains a File
>Entry rather
>> -  // than an Extended File Entry (which is not recommended as per
>spec), we
>> need
>> -  // to make sure the size of a FE will be _at least_ 2048
>> -  // (UDF_LOGICAL_SECTOR_SIZE) bytes long to keep backward
>compatibility.
>> +  // Determine FE (File Entry) size
>>    //
>> -  LogicalBlockSize = LV_BLOCK_SIZE (Volume, UDF_DEFAULT_LV_NUM);
>> +  LogicalBlockSize = Volume->LogicalVolDesc.LogicalBlockSize;
>>    if (LogicalBlockSize >= UDF_LOGICAL_SECTOR_SIZE) {
>> -    Volume->FileEntrySize = LogicalBlockSize;
>> +    Volume->FileEntrySize = (UINTN)LogicalBlockSize;
>>    } else {
>>      Volume->FileEntrySize = UDF_LOGICAL_SECTOR_SIZE;
>>    }
>> 
>> -  FreePool (Buffer);
>> +  Status = EFI_SUCCESS;
>> 
>> -  return EFI_SUCCESS;
>> -
>> -Error_Alloc_Pd:
>> -Error_Alloc_Lvd:
>> -  for (Index = 0; Index < Volume->PartitionDescsNo; Index++) {
>> -    FreePool ((VOID *)Volume->PartitionDescs[Index]);
>> -  }
>> -
>> -  for (Index = 0; Index < Volume->LogicalVolDescsNo; Index++) {
>> -    FreePool ((VOID *)Volume->LogicalVolDescs[Index]);
>> -  }
>> -
>> -Error_Read_Disk_Blk:
>> +Out_Free:
>> +  //
>> +  // Free block read buffer
>> +  //
>>    FreePool (Buffer);
>> 
>> -Error_Alloc_Buf:
>> -  FreePool ((VOID *)Volume->PartitionDescs);
>> -  Volume->PartitionDescs = NULL;
>> -
>> -Error_Alloc_Pds:
>> -  FreePool ((VOID *)Volume->LogicalVolDescs);
>> -  Volume->LogicalVolDescs = NULL;
>> -
>>    return Status;
>>  }
>> 
>> @@ -262,48 +216,53 @@ GetPdFromLongAd (
>>    )
>>  {
>>    UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;
>> -  UINTN                          Index;
>> -  UDF_PARTITION_DESCRIPTOR       *PartitionDesc;
>>    UINT16                         PartitionNum;
>> 
>> -  LogicalVolDesc = Volume->LogicalVolDescs[UDF_DEFAULT_LV_NUM];
>> +  LogicalVolDesc = &Volume->LogicalVolDesc;
>> 
>> -  switch (LV_UDF_REVISION (LogicalVolDesc)) {
>> +  switch (UDF_LVD_REVISION (LogicalVolDesc)) {
>>    case 0x0102:
>> +  case 0x0150:
>> +  case 0x0200:
>> +  case 0x0201:
>> +  case 0x0250:
>> +  case 0x0260:
>>      //
>> -    // As per UDF 1.02 specification:
>> +    // UDF 1.02 specification:
>>      //
>>      // There shall be exactly one prevailing Logical Volume
>Descriptor recorded
>>      // per Volume Set. The Partition Maps field shall contain only
>Type 1
>>      // Partition Maps.
>>      //
>> -    PartitionNum = *(UINT16
>*)((UINTN)&LogicalVolDesc->PartitionMaps[4]);
>> -    break;
>> -  case 0x0150:
>> +    // UDF 1.50 through 2.60 specs say:
>>      //
>> -    // Ensure Type 1 Partition map. Other types aren't supported in
>this
>> -    // implementation.
>> +    // For the purpose of interchange partition maps shall be
>limited to
>> +    // Partition Map type 1, except type 2 maps as described in the
>document.
>> +    //
>> +    // NOTE: Only one Type 1 (Physical) Partition is supported. It
>has been
>> +    // checked already in Partition driver for existence of a single
>Type 1
>> +    // Partition map, so we don't have to double check here.
>> +    //
>> +    // Partition reference number can also be retrieved from
>> +    // LongAd->ExtentLocation.PartitionReferenceNumber, however the
>spec
>> says
>> +    // it may be 0, so let's not rely on it.
>>      //
>> -    if (LogicalVolDesc->PartitionMaps[0] != 1 ||
>> -        LogicalVolDesc->PartitionMaps[1] != 6) {
>> -      return NULL;
>> -    }
>>      PartitionNum = *(UINT16
>*)((UINTN)&LogicalVolDesc->PartitionMaps[4]);
>>      break;
>> -  case 0x0260:
>> +
>> +  default:
>>      //
>> -    // Fall through.
>> +    // Unsupported UDF revision
>>      //
>> -  default:
>> -    PartitionNum = LongAd->ExtentLocation.PartitionReferenceNumber;
>> -    break;
>> +    return NULL;
>>    }
>> 
>> -  for (Index = 0; Index < Volume->PartitionDescsNo; Index++) {
>> -    PartitionDesc = Volume->PartitionDescs[Index];
>> -    if (PartitionDesc->PartitionNumber == PartitionNum) {
>> -      return PartitionDesc;
>> -    }
>> +  //
>> +  // Check if partition number matches Partition Descriptor found in
>Main
>> Volume
>> +  // Descriptor Sequence.
>> +  //
>> +  if (Volume->PartitionDesc.PartitionNumber == PartitionNum) {
>> +    return &Volume->PartitionDesc;
>>    }
>> 
>>    return NULL;
>> @@ -329,13 +288,15 @@ GetLongAdLsn (
>>    PartitionDesc = GetPdFromLongAd (Volume, LongAd);
>>    ASSERT (PartitionDesc != NULL);
>> 
>> -  return (UINT64)PartitionDesc->PartitionStartingLocation +
>> -                 LongAd->ExtentLocation.LogicalBlockNumber;
>> +  return (UINT64)PartitionDesc->PartitionStartingLocation -
>> +    Volume->MainVdsStartLocation +
>> +    LongAd->ExtentLocation.LogicalBlockNumber;
>>  }
>> 
>>  /**
>>    Return logical sector number of a given Short Allocation
>Descriptor.
>> 
>> +  @param[in]  Volume              Volume pointer.
>>    @param[in]  PartitionDesc       Partition Descriptor pointer.
>>    @param[in]  ShortAd             Short Allocation Descriptor
>pointer.
>> 
>> @@ -344,14 +305,13 @@ GetLongAdLsn (
>>  **/
>>  UINT64
>>  GetShortAdLsn (
>> +  IN UDF_VOLUME_INFO                  *Volume,
>>    IN UDF_PARTITION_DESCRIPTOR         *PartitionDesc,
>>    IN UDF_SHORT_ALLOCATION_DESCRIPTOR  *ShortAd
>>    )
>>  {
>> -  ASSERT (PartitionDesc != NULL);
>> -
>> -  return (UINT64)PartitionDesc->PartitionStartingLocation +
>> -    ShortAd->ExtentPosition;
>> +  return (UINT64)PartitionDesc->PartitionStartingLocation -
>> +    Volume->MainVdsStartLocation + ShortAd->ExtentPos

--
Sent from my Android device with K-9 Mail. Please excuse my brevity.
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Re: [edk2] [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix creation of UDF logical partition
Posted by Paulo Alcantara 7 years, 3 months ago

On September 21, 2017 10:47:07 AM GMT-03:00, "Zeng, Star" <star.zeng@intel.com> wrote:
>Does it have functional impact?

Nope. When Partition driver walks the partition detect routine table, it executes each routine and then checks for EFI_NO_MEDIA and EFI_MEDIA_CHANGED only. So, the child handle is installed and the EFI_NOT_FOUND is a no-op in that case.

Thanks!
Paulo

>
>Thanks,
>Star
>-----Original Message-----
>From: Paulo Alcantara [mailto:pcacjr@zytor.com] 
>Sent: Thursday, September 21, 2017 9:29 PM
>To: Wu, Hao A <hao.a.wu@intel.com>; edk2-devel@lists.01.org
>Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Laszlo Ersek <lersek@redhat.com>;
>Dong, Eric <eric.dong@intel.com>; Zeng, Star <star.zeng@intel.com>
>Subject: RE: [edk2] [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix
>creation of UDF logical partition
>
>
>
>On September 21, 2017 9:44:10 AM GMT-03:00, "Wu, Hao A"
><hao.a.wu@intel.com> wrote:
>>One small comment, within function PartitionInstallUdfChildHandles():
>>
>>  ...
>>  //
>>  // Install partition child handle for UDF file system
>>  //
>>  Status = PartitionInstallChildHandle (
>>    ...
>>    );
>>if (!EFI_ERROR (Status)) {  <----- Is this a typo? "if (EFI_ERROR
>>(Status)) {"  
>>    Status = EFI_NOT_FOUND;
>>  }
>
>Yes, it is. Good catch! Could you please fix that for me by removing
>the if condition? Otherwise I can send a v4 later with that.
>
>Thanks!
>Paulo
>
>>  
>>
>>Best Regards,
>>Hao Wu
>>
>>
>>> -----Original Message-----
>>> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf
>>Of Paulo
>>> Alcantara
>>> Sent: Thursday, September 21, 2017 2:16 AM
>>> To: edk2-devel@lists.01.org
>>> Cc: Ni, Ruiyu; Laszlo Ersek; Dong, Eric; Zeng, Star
>>> Subject: [edk2] [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix
>>creation of
>>> UDF logical partition
>>> 
>>> Do not reserve entire block device size for an UDF file system - 
>>> instead, reserve the appropriate space (UDF logical volume space)
>for 
>>> it.
>>> 
>>> Additionally, only create a logical partition for UDF logical
>volumes 
>>> that are currently supported by EDK2 UDF file system implementation.
>>For
>>> instance, an UDF volume with a single LVD and a single Physical
>(Type
>>1)
>>> Partition will be supported.
>>> 
>>> Cc: Eric Dong <eric.dong@intel.com>
>>> Cc: Ruiyu Ni <ruiyu.ni@intel.com>
>>> Cc: Star Zeng <star.zeng@intel.com>
>>> Cc: Laszlo Ersek <lersek@redhat.com>
>>> Reported-by: Ruiyu Ni <ruiyu.ni@intel.com>
>>> Contributed-under: TianoCore Contribution Agreement 1.1
>>> Signed-off-by: Paulo Alcantara <pcacjr@zytor.com>
>>> ---
>>>  MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c            | 363
>>++++++++++--
>>>  MdeModulePkg/Universal/Disk/UdfDxe/File.c                 |  16 +-
>>>  MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c | 627
>>> ++++++++------------
>>>  MdeModulePkg/Universal/Disk/UdfDxe/Udf.c                  |   7 -
>>>  MdeModulePkg/Universal/Disk/UdfDxe/Udf.h                  | 158
>>++---
>>>  5 files changed, 606 insertions(+), 565 deletions(-)
>>> 
>>> diff --git a/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
>>> b/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
>>> index 609f56cef6..572ba7a81a 100644
>>> --- a/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
>>> +++ b/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
>>> @@ -64,11 +64,12 @@ FindAnchorVolumeDescriptorPointer (
>>>    OUT  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint
>>>    )
>>>  {
>>> -  EFI_STATUS  Status;
>>> -  UINT32      BlockSize;
>>> -  EFI_LBA     EndLBA;
>>> -  EFI_LBA     DescriptorLBAs[4];
>>> -  UINTN       Index;
>>> +  EFI_STATUS          Status;
>>> +  UINT32              BlockSize;
>>> +  EFI_LBA             EndLBA;
>>> +  EFI_LBA             DescriptorLBAs[4];
>>> +  UINTN               Index;
>>> +  UDF_DESCRIPTOR_TAG  *DescriptorTag;
>>> 
>>>    BlockSize = BlockIo->Media->BlockSize;
>>>    EndLBA = BlockIo->Media->LastBlock; @@ -88,10 +89,13 @@ 
>>> FindAnchorVolumeDescriptorPointer (
>>>      if (EFI_ERROR (Status)) {
>>>        return Status;
>>>      }
>>> +
>>> +    DescriptorTag = &AnchorPoint->DescriptorTag;
>>> +
>>>      //
>>>      // Check if read LBA has a valid AVDP descriptor.
>>>      //
>>> -    if (IS_AVDP (AnchorPoint)) {
>>> +    if (DescriptorTag->TagIdentifier ==
>>UdfAnchorVolumeDescriptorPointer) {
>>>        return EFI_SUCCESS;
>>>      }
>>>    }
>>> @@ -102,23 +106,18 @@ FindAnchorVolumeDescriptorPointer (  }
>>> 
>>>  /**
>>> -  Check if block device supports a valid UDF file system as
>>specified by OSTA
>>> -  Universal Disk Format Specification 2.60.
>>> +  Find UDF volume identifiers in a Volume Recognition Sequence.
>>> 
>>> -  @param[in]   BlockIo  BlockIo interface.
>>> -  @param[in]   DiskIo   DiskIo interface.
>>> +  @param[in]  BlockIo             BlockIo interface.
>>> +  @param[in]  DiskIo              DiskIo interface.
>>> 
>>> -  @retval EFI_SUCCESS          UDF file system found.
>>> -  @retval EFI_UNSUPPORTED      UDF file system not found.
>>> -  @retval EFI_NO_MEDIA         The device has no media.
>>> -  @retval EFI_DEVICE_ERROR     The device reported an error.
>>> -  @retval EFI_VOLUME_CORRUPTED The file system structures are
>>corrupted.
>>> -  @retval EFI_OUT_OF_RESOURCES The scan was not successful due to
>>lack of
>>> -                               resources.
>>> +  @retval EFI_SUCCESS             UDF volume identifiers were
>found.
>>> +  @retval EFI_NOT_FOUND           UDF volume identifiers were not
>>found.
>>> +  @retval other                   Failed to perform disk I/O.
>>> 
>>>  **/
>>>  EFI_STATUS
>>> -SupportUdfFileSystem (
>>> +FindUdfVolumeIdentifiers (
>>>    IN EFI_BLOCK_IO_PROTOCOL  *BlockIo,
>>>    IN EFI_DISK_IO_PROTOCOL   *DiskIo
>>>    )
>>> @@ -128,7 +127,6 @@ SupportUdfFileSystem (
>>>    UINT64                                EndDiskOffset;
>>>    CDROM_VOLUME_DESCRIPTOR               VolDescriptor;
>>>    CDROM_VOLUME_DESCRIPTOR               TerminatingVolDescriptor;
>>> -  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  AnchorPoint;
>>> 
>>>    ZeroMem ((VOID *)&TerminatingVolDescriptor, sizeof 
>>> (CDROM_VOLUME_DESCRIPTOR));
>>> 
>>> @@ -167,7 +165,7 @@ SupportUdfFileSystem (
>>>          (CompareMem ((VOID *)&VolDescriptor,
>>>                       (VOID *)&TerminatingVolDescriptor,
>>>                       sizeof (CDROM_VOLUME_DESCRIPTOR)) == 0)) {
>>> -      return EFI_UNSUPPORTED;
>>> +      return EFI_NOT_FOUND;
>>>      }
>>>    }
>>> 
>>> @@ -176,7 +174,7 @@ SupportUdfFileSystem (
>>>    //
>>>    Offset += UDF_LOGICAL_SECTOR_SIZE;
>>>    if (Offset >= EndDiskOffset) {
>>> -    return EFI_UNSUPPORTED;
>>> +    return EFI_NOT_FOUND;
>>>    }
>>> 
>>>    Status = DiskIo->ReadDisk (
>>> @@ -196,7 +194,7 @@ SupportUdfFileSystem (
>>>        (CompareMem ((VOID *)VolDescriptor.Unknown.Id,
>>>                     (VOID *)UDF_NSR3_IDENTIFIER,
>>>                     sizeof (VolDescriptor.Unknown.Id)) != 0)) {
>>> -    return EFI_UNSUPPORTED;
>>> +    return EFI_NOT_FOUND;
>>>    }
>>> 
>>>    //
>>> @@ -204,7 +202,7 @@ SupportUdfFileSystem (
>>>    //
>>>    Offset += UDF_LOGICAL_SECTOR_SIZE;
>>>    if (Offset >= EndDiskOffset) {
>>> -    return EFI_UNSUPPORTED;
>>> +    return EFI_NOT_FOUND;
>>>    }
>>> 
>>>    Status = DiskIo->ReadDisk (
>>> @@ -221,15 +219,291 @@ SupportUdfFileSystem (
>>>    if (CompareMem ((VOID *)VolDescriptor.Unknown.Id,
>>>                    (VOID *)UDF_TEA_IDENTIFIER,
>>>                    sizeof (VolDescriptor.Unknown.Id)) != 0) {
>>> -    return EFI_UNSUPPORTED;
>>> +    return EFI_NOT_FOUND;
>>> +  }
>>> +
>>> +  return EFI_SUCCESS;
>>> +}
>>> +
>>> +/**
>>> +  Check if Logical Volume Descriptor is supported by current EDK2
>>UDF file
>>> +  system implementation.
>>> +
>>> +  @param[in]  LogicalVolDesc  Logical Volume Descriptor pointer.
>>> +
>>> +  @retval TRUE                Logical Volume Descriptor is
>>supported.
>>> +  @retval FALSE               Logical Volume Descriptor is not
>>supported.
>>> +
>>> +**/
>>> +BOOLEAN
>>> +IsLogicalVolumeDescriptorSupported (
>>> +  UDF_LOGICAL_VOLUME_DESCRIPTOR *LogicalVolDesc
>>> +  )
>>> +{
>>> +  //
>>> +  // Check for a valid UDF revision range
>>> +  //
>>> +  switch (UDF_LVD_REVISION (LogicalVolDesc)) {
>>> +  case 0x0102:
>>> +  case 0x0150:
>>> +  case 0x0200:
>>> +  case 0x0201:
>>> +  case 0x0250:
>>> +  case 0x0260:
>>> +    break;
>>> +  default:
>>> +    return FALSE;
>>> +  }
>>> +
>>> +  //
>>> +  // Check for a single Partition Map  //  if 
>>> + (LogicalVolDesc->NumberOfPartitionMaps > 1) {
>>> +    return FALSE;
>>> +  }
>>> +  //
>>> +  // UDF 1.02 revision supports only Type 1 (Physical) partitions,
>>but
>>> +  // let's check it any way.
>>> +  //
>>> +  // PartitionMap[0] -> type
>>> +  // PartitionMap[1] -> length (in bytes)  //  if 
>>> + (LogicalVolDesc->PartitionMaps[0] != 1 ||
>>> +      LogicalVolDesc->PartitionMaps[1] != 6) {
>>> +    return FALSE;
>>> +  }
>>> +
>>> +  return TRUE;
>>> +}
>>> +
>>> +/**
>>> +  Find UDF logical volume location and whether it is supported by
>>current EDK2
>>> +  UDF file system implementation.
>>> +
>>> +  @param[in]  BlockIo             BlockIo interface.
>>> +  @param[in]  DiskIo              DiskIo interface.
>>> +  @param[in]  AnchorPoint         Anchor volume descriptor pointer.
>>> +  @param[out] MainVdsStartBlock   Main VDS starting block number.
>>> +  @param[out] MainVdsEndBlock     Main VDS ending block number.
>>> +
>>> +  @retval EFI_SUCCESS             UDF logical volume was found.
>>> +  @retval EFI_VOLUME_CORRUPTED    UDF file system structures are
>>> corrupted.
>>> +  @retval EFI_UNSUPPORTED         UDF logical volume is not
>>supported.
>>> +  @retval other                   Failed to perform disk I/O.
>>> +
>>> +**/
>>> +EFI_STATUS
>>> +FindLogicalVolumeLocation (
>>> +  IN   EFI_BLOCK_IO_PROTOCOL                 *BlockIo,
>>> +  IN   EFI_DISK_IO_PROTOCOL                  *DiskIo,
>>> +  IN   UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint,
>>> +  OUT  UINT64                                *MainVdsStartBlock,
>>> +  OUT  UINT64                                *MainVdsEndBlock
>>> +  )
>>> +{
>>> +  EFI_STATUS                     Status;
>>> +  UINT32                         BlockSize;
>>> +  EFI_LBA                        LastBlock;
>>> +  UDF_EXTENT_AD                  *ExtentAd;
>>> +  UINT64                         SeqBlocksNum;
>>> +  UINT64                         SeqStartBlock;
>>> +  UINT64                         GuardMainVdsStartBlock;
>>> +  VOID                           *Buffer;
>>> +  UINT64                         SeqEndBlock;
>>> +  BOOLEAN                        StopSequence;
>>> +  UINTN                          LvdsCount;
>>> +  UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;
>>> +  UDF_DESCRIPTOR_TAG             *DescriptorTag;
>>> +
>>> +  BlockSize = BlockIo->Media->BlockSize;  LastBlock = 
>>> + BlockIo->Media->LastBlock;  ExtentAd = 
>>> + &AnchorPoint->MainVolumeDescriptorSequenceExtent;
>>> +
>>> +  //
>>> +  // UDF 2.60, 2.2.3.1 struct MainVolumeDescriptorSequenceExtent
>>> +  //
>>> +  // The Main Volume Descriptor Sequence Extent shall have a
>minimum
>>length
>>> of
>>> +  // 16 logical sectors.
>>> +  //
>>> +  // Also make sure it does not exceed maximum number of blocks in
>>the disk.
>>> +  //
>>> +  SeqBlocksNum = DivU64x32 ((UINT64)ExtentAd->ExtentLength,
>>BlockSize);
>>> +  if (SeqBlocksNum < 16 || (EFI_LBA)SeqBlocksNum > LastBlock + 1) {
>>> +    return EFI_VOLUME_CORRUPTED;
>>> +  }
>>> +
>>> +  //
>>> +  // Check for valid Volume Descriptor Sequence starting block
>>number
>>> +  //
>>> +  SeqStartBlock = (UINT64)ExtentAd->ExtentLocation;  if 
>>> + (SeqStartBlock > LastBlock ||
>>> +      SeqStartBlock + SeqBlocksNum - 1 > LastBlock) {
>>> +    return EFI_VOLUME_CORRUPTED;
>>>    }
>>> 
>>> +  GuardMainVdsStartBlock = SeqStartBlock;
>>> +
>>> +  //
>>> +  // Allocate buffer for reading disk blocks  //  Buffer = 
>>> + AllocateZeroPool ((UINTN)BlockSize);  if (Buffer == NULL) {
>>> +    return EFI_OUT_OF_RESOURCES;
>>> +  }
>>> +
>>> +  SeqEndBlock = SeqStartBlock + SeqBlocksNum;  StopSequence =
>FALSE;  
>>> + LvdsCount = 0;  Status = EFI_VOLUME_CORRUPTED;  //  // Start Main 
>>> + Volume Descriptor Sequence  //  for (; SeqStartBlock < SeqEndBlock
>
>>> + && !StopSequence;
>>SeqStartBlock++) {
>>> +    //
>>> +    // Read disk block
>>> +    //
>>> +    Status = BlockIo->ReadBlocks (
>>> +      BlockIo,
>>> +      BlockIo->Media->MediaId,
>>> +      SeqStartBlock,
>>> +      BlockSize,
>>> +      Buffer
>>> +      );
>>> +    if (EFI_ERROR (Status)) {
>>> +      goto Out_Free;
>>> +    }
>>> +
>>> +    DescriptorTag = Buffer;
>>> +
>>> +    //
>>> +    // ECMA 167, 8.4.1 Contents of a Volume Descriptor Sequence
>>> +    //
>>> +    // - A Volume Descriptor Sequence shall contain one or more
>>Primary
>>> Volume
>>> +    //   Descriptors.
>>> +    // - A Volume Descriptor Sequence shall contain zero or more
>>> Implementation
>>> +    //   Use Volume Descriptors.
>>> +    // - A Volume Descriptor Sequence shall contain zero or more
>>Partition
>>> +    //   Descriptors.
>>> +    // - A Volume Descriptor Sequence shall contain zero or more
>>Logical
>>> Volume
>>> +    //   Descriptors.
>>> +    // - A Volume Descriptor Sequence shall contain zero or more
>>Unallocated
>>> +    //   Space Descriptors.
>>> +    //
>>> +    switch (UDF_TAG_ID (DescriptorTag)) {
>>> +    case UdfPrimaryVolumeDescriptor:
>>> +    case UdfImplemenationUseVolumeDescriptor:
>>> +    case UdfPartitionDescriptor:
>>> +    case UdfUnallocatedSpaceDescriptor:
>>> +      break;
>>> +
>>> +    case UdfLogicalVolumeDescriptor:
>>> +      LogicalVolDesc = Buffer;
>>> +
>>> +      //
>>> +      // Check for existence of a single LVD and whether it is
>>supported by
>>> +      // current EDK2 UDF file system implementation.
>>> +      //
>>> +      if (++LvdsCount > 1 ||
>>> +          !IsLogicalVolumeDescriptorSupported (LogicalVolDesc)) {
>>> +        Status = EFI_UNSUPPORTED;
>>> +        StopSequence = TRUE;
>>> +      }
>>> +
>>> +      break;
>>> +
>>> +    case UdfTerminatingDescriptor:
>>> +      //
>>> +      // Stop the sequence when we find a Terminating Descriptor
>>> +      // (aka Unallocated Sector), se we don't have to walk all the
>>unallocated
>>> +      // area unnecessarily.
>>> +      //
>>> +      StopSequence = TRUE;
>>> +      break;
>>> +
>>> +    default:
>>> +      //
>>> +      // An invalid Volume Descriptor has been found in the
>sequece.
>>Volume is
>>> +      // corrupted.
>>> +      //
>>> +      Status = EFI_VOLUME_CORRUPTED;
>>> +      goto Out_Free;
>>> +    }
>>> +  }
>>> +
>>> +  //
>>> +  // Check if LVD was found
>>> +  //
>>> +  if (!EFI_ERROR (Status) && LvdsCount == 1) {
>>> +    *MainVdsStartBlock = GuardMainVdsStartBlock;
>>> +    //
>>> +    // We do not need to read either LVD or PD descriptors to know
>>the last
>>> +    // valid block in the found UDF file system. It's already
>>LastBlock.
>>> +    //
>>> +    *MainVdsEndBlock = LastBlock;
>>> +
>>> +    Status = EFI_SUCCESS;
>>> +  }
>>> +
>>> +Out_Free:
>>> +  //
>>> +  // Free block read buffer
>>> +  //
>>> +  FreePool (Buffer);
>>> +
>>> +  return Status;
>>> +}
>>> +
>>> +/**
>>> +  Find a supported UDF file system in block device.
>>> +
>>> +  @param[in]  BlockIo             BlockIo interface.
>>> +  @param[in]  DiskIo              DiskIo interface.
>>> +  @param[out] StartingLBA         UDF file system starting LBA.
>>> +  @param[out] EndingLBA           UDF file system starting LBA.
>>> +
>>> +  @retval EFI_SUCCESS             UDF file system was found.
>>> +  @retval other                   UDF file system was not found.
>>> +
>>> +**/
>>> +EFI_STATUS
>>> +FindUdfFileSystem (
>>> +  IN EFI_BLOCK_IO_PROTOCOL  *BlockIo,
>>> +  IN EFI_DISK_IO_PROTOCOL   *DiskIo,
>>> +  OUT EFI_LBA               *StartingLBA,
>>> +  OUT EFI_LBA               *EndingLBA
>>> +  )
>>> +{
>>> +  EFI_STATUS Status;
>>> +  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  AnchorPoint;
>>> +
>>> +  //
>>> +  // Find UDF volume identifiers
>>> +  //
>>> +  Status = FindUdfVolumeIdentifiers (BlockIo, DiskIo);  if 
>>> + (EFI_ERROR (Status)) {
>>> +    return Status;
>>> +  }
>>> +
>>> +  //
>>> +  // Find Anchor Volume Descriptor Pointer  //
>>>    Status = FindAnchorVolumeDescriptorPointer (BlockIo, DiskIo,
>>&AnchorPoint);
>>>    if (EFI_ERROR (Status)) {
>>> -    return EFI_UNSUPPORTED;
>>> +    return Status;
>>>    }
>>> 
>>> -  return EFI_SUCCESS;
>>> +  //
>>> +  // Find Logical Volume location
>>> +  //
>>> +  Status = FindLogicalVolumeLocation (
>>> +    BlockIo,
>>> +    DiskIo,
>>> +    &AnchorPoint,
>>> +    (UINT64 *)StartingLBA,
>>> +    (UINT64 *)EndingLBA
>>> +    );
>>> +
>>> +  return Status;
>>>  }
>>> 
>>>  /**
>>> @@ -263,9 +537,9 @@ PartitionInstallUdfChildHandles (
>>>    UINT32                       RemainderByMediaBlockSize;
>>>    EFI_STATUS                   Status;
>>>    EFI_BLOCK_IO_MEDIA           *Media;
>>> -  EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode;
>>> -  EFI_GUID                     *VendorDefinedGuid;
>>>    EFI_PARTITION_INFO_PROTOCOL  PartitionInfo;
>>> +  EFI_LBA                      StartingLBA;
>>> +  EFI_LBA                      EndingLBA;
>>> 
>>>    Media = BlockIo->Media;
>>> 
>>> @@ -281,35 +555,10 @@ PartitionInstallUdfChildHandles (
>>>      return EFI_NOT_FOUND;
>>>    }
>>> 
>>> -  DevicePathNode = DevicePath;
>>> -  while (!IsDevicePathEnd (DevicePathNode)) {
>>> -    //
>>> -    // Do not allow checking for UDF file systems in CDROM "El
>>Torito"
>>> -    // partitions, and skip duplicate installation of UDF file
>>system child
>>> -    // nodes.
>>> -    //
>>> -    if (DevicePathType (DevicePathNode) == MEDIA_DEVICE_PATH) {
>>> -      if (DevicePathSubType (DevicePathNode) == MEDIA_CDROM_DP) {
>>> -        return EFI_NOT_FOUND;
>>> -      }
>>> -      if (DevicePathSubType (DevicePathNode) == MEDIA_VENDOR_DP) {
>>> -        VendorDefinedGuid = (EFI_GUID *)((UINTN)DevicePathNode +
>>> -                                         OFFSET_OF
>>(VENDOR_DEVICE_PATH, Guid));
>>> -        if (CompareGuid (VendorDefinedGuid, &gUdfDevPathGuid)) {
>>> -          return EFI_NOT_FOUND;
>>> -        }
>>> -      }
>>> -    }
>>> -    //
>>> -    // Try next device path node
>>> -    //
>>> -    DevicePathNode = NextDevicePathNode (DevicePathNode);
>>> -  }
>>> -
>>>    //
>>> -  // Check if block device supports an UDF file system
>>> +  // Search for an UDF file system on block device
>>>    //
>>> -  Status = SupportUdfFileSystem (BlockIo, DiskIo);
>>> +  Status = FindUdfFileSystem (BlockIo, DiskIo, &StartingLBA,
>>&EndingLBA);
>>>    if (EFI_ERROR (Status)) {
>>>      return EFI_NOT_FOUND;
>>>    }
>>> @@ -334,8 +583,8 @@ PartitionInstallUdfChildHandles (
>>>      DevicePath,
>>>      (EFI_DEVICE_PATH_PROTOCOL *)&gUdfDevicePath,
>>>      &PartitionInfo,
>>> -    0,
>>> -    Media->LastBlock,
>>> +    StartingLBA,
>>> +    EndingLBA,
>>>      Media->BlockSize
>>>      );
>>>    if (!EFI_ERROR (Status)) {
>>> diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/File.c
>>> b/MdeModulePkg/Universal/Disk/UdfDxe/File.c
>>> index 625f2c5637..6f07bf2066 100644
>>> --- a/MdeModulePkg/Universal/Disk/UdfDxe/File.c
>>> +++ b/MdeModulePkg/Universal/Disk/UdfDxe/File.c
>>> @@ -131,7 +131,6 @@ Error_Alloc_Priv_File_Data:
>>>    CleanupFileInformation (&PrivFsData->Root);
>>> 
>>>  Error_Find_Root_Dir:
>>> -  CleanupVolumeInformation (&PrivFsData->Volume);
>>> 
>>>  Error_Read_Udf_Volume:
>>>  Error_Invalid_Params:
>>> @@ -429,7 +428,7 @@ UdfRead (
>>>      }
>>>      ASSERT (NewFileEntryData != NULL);
>>> 
>>> -    if (IS_FE_SYMLINK (NewFileEntryData)) {
>>> +    if (FE_ICB_FILE_TYPE (NewFileEntryData) == UdfFileEntrySymlink)
>>{
>>>        Status = ResolveSymlink (
>>>          BlockIo,
>>>          DiskIo,
>>> @@ -529,7 +528,6 @@ UdfClose (
>>>    EFI_TPL                     OldTpl;
>>>    EFI_STATUS                  Status;
>>>    PRIVATE_UDF_FILE_DATA       *PrivFileData;
>>> -  PRIVATE_UDF_SIMPLE_FS_DATA  *PrivFsData;
>>> 
>>>    OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
>>> 
>>> @@ -542,8 +540,6 @@ UdfClose (
>>> 
>>>    PrivFileData = PRIVATE_UDF_FILE_DATA_FROM_THIS (This);
>>> 
>>> -  PrivFsData = PRIVATE_UDF_SIMPLE_FS_DATA_FROM_THIS (PrivFileData-
>>> >SimpleFs);
>>> -
>>>    if (!PrivFileData->IsRootDirectory) {
>>>      CleanupFileInformation (&PrivFileData->File);
>>> 
>>> @@ -552,10 +548,6 @@ UdfClose (
>>>      }
>>>    }
>>> 
>>> -  if (--PrivFsData->OpenFiles == 0) {
>>> -    CleanupVolumeInformation (&PrivFsData->Volume);
>>> -  }
>>> -
>>>    FreePool ((VOID *)PrivFileData);
>>> 
>>>  Exit:
>>> @@ -652,7 +644,7 @@ UdfGetPosition (
>>>    // As per UEFI spec, if the file handle is a directory, then the
>>current file
>>>    // position has no meaning and the operation is not supported.
>>>    //
>>> -  if (IS_FID_DIRECTORY_FILE
>>(&PrivFileData->File.FileIdentifierDesc)) {
>>> +  if (IS_FID_DIRECTORY_FILE
>(PrivFileData->File.FileIdentifierDesc))
>>{
>>>      return  EFI_UNSUPPORTED;
>>>    }
>>> 
>>> @@ -788,7 +780,7 @@ UdfGetInfo (
>>>    } else if (CompareGuid (InformationType,
>&gEfiFileSystemInfoGuid))
>>{
>>>      String = VolumeLabel;
>>> 
>>> -    FileSetDesc = PrivFsData->Volume.FileSetDescs[0];
>>> +    FileSetDesc = &PrivFsData->Volume.FileSetDesc;
>>> 
>>>      OstaCompressed = &FileSetDesc->LogicalVolumeIdentifier[0];
>>> 
>>> @@ -847,7 +839,7 @@ UdfGetInfo (
>>>      FileSystemInfo->Size        = FileSystemInfoLength;
>>>      FileSystemInfo->ReadOnly    = TRUE;
>>>      FileSystemInfo->BlockSize   =
>>> -      LV_BLOCK_SIZE (&PrivFsData->Volume, UDF_DEFAULT_LV_NUM);
>>> +      PrivFsData->Volume.LogicalVolDesc.LogicalBlockSize;
>>>      FileSystemInfo->VolumeSize  = VolumeSize;
>>>      FileSystemInfo->FreeSpace   = FreeSpaceSize;
>>> 
>>> diff --git
>>a/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
>>> b/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
>>> index 5df267761f..62d817989f 100644
>>> --- a/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
>>> +++ b/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
>>> @@ -38,11 +38,12 @@ FindAnchorVolumeDescriptorPointer (
>>>    OUT  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint
>>>    )
>>>  {
>>> -  EFI_STATUS  Status;
>>> -  UINT32      BlockSize;
>>> -  EFI_LBA     EndLBA;
>>> -  EFI_LBA     DescriptorLBAs[4];
>>> -  UINTN       Index;
>>> +  EFI_STATUS          Status;
>>> +  UINT32              BlockSize;
>>> +  EFI_LBA             EndLBA;
>>> +  EFI_LBA             DescriptorLBAs[4];
>>> +  UINTN               Index;
>>> +  UDF_DESCRIPTOR_TAG  *DescriptorTag;
>>> 
>>>    BlockSize = BlockIo->Media->BlockSize;
>>>    EndLBA = BlockIo->Media->LastBlock; @@ -62,10 +63,13 @@ 
>>> FindAnchorVolumeDescriptorPointer (
>>>      if (EFI_ERROR (Status)) {
>>>        return Status;
>>>      }
>>> +
>>> +    DescriptorTag = &AnchorPoint->DescriptorTag;
>>> +
>>>      //
>>>      // Check if read LBA has a valid AVDP descriptor.
>>>      //
>>> -    if (IS_AVDP (AnchorPoint)) {
>>> +    if (DescriptorTag->TagIdentifier ==
>>UdfAnchorVolumeDescriptorPointer) {
>>>        return EFI_SUCCESS;
>>>      }
>>>    }
>>> @@ -99,148 +103,98 @@ StartMainVolumeDescriptorSequence (
>>>    OUT  UDF_VOLUME_INFO                       *Volume
>>>    )
>>>  {
>>> -  EFI_STATUS                     Status;
>>> -  UINT32                         BlockSize;
>>> -  UDF_EXTENT_AD                  *ExtentAd;
>>> -  UINT64                         StartingLsn;
>>> -  UINT64                         EndingLsn;
>>> -  VOID                           *Buffer;
>>> -  UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;
>>> -  UDF_PARTITION_DESCRIPTOR       *PartitionDesc;
>>> -  UINTN                          Index;
>>> -  UINT32                         LogicalBlockSize;
>>> +  EFI_STATUS            Status;
>>> +  UINT32                BlockSize;
>>> +  UDF_EXTENT_AD         *ExtentAd;
>>> +  EFI_LBA               SeqStartBlock;
>>> +  EFI_LBA               SeqEndBlock;
>>> +  BOOLEAN               StopSequence;
>>> +  VOID                  *Buffer;
>>> +  UDF_DESCRIPTOR_TAG    *DescriptorTag;
>>> +  UINT32                LogicalBlockSize;
>>> +
>>> +  BlockSize = BlockIo->Media->BlockSize;  ExtentAd = 
>>> + &AnchorPoint->MainVolumeDescriptorSequenceExtent;
>>> 
>>>    //
>>> -  // We've already found an ADVP on the volume. It contains the
>>extent
>>> -  // (MainVolumeDescriptorSequenceExtent) where the Main Volume 
>>> Descriptor
>>> -  // Sequence starts. Therefore, we'll look for Logical Volume
>>Descriptors and
>>> -  // Partitions Descriptors and save them in memory, accordingly.
>>> -  //
>>> -  // Note also that each descriptor will be aligned on a block size
>>(BlockSize)
>>> -  // boundary, so we need to read one block at a time.
>>> +  // Allocate buffer for reading disk blocks
>>>    //
>>> -  BlockSize    = BlockIo->Media->BlockSize;
>>> -  ExtentAd     = &AnchorPoint->MainVolumeDescriptorSequenceExtent;
>>> -  StartingLsn  = (UINT64)ExtentAd->ExtentLocation;
>>> -  EndingLsn    = StartingLsn + DivU64x32 (
>>> -                                    
>(UINT64)ExtentAd->ExtentLength,
>>> -                                     BlockSize
>>> -                                     );
>>> -
>>> -  Volume->LogicalVolDescs =
>>> -    (UDF_LOGICAL_VOLUME_DESCRIPTOR **)AllocateZeroPool (ExtentAd-
>>> >ExtentLength);
>>> -  if (Volume->LogicalVolDescs == NULL) {
>>> -    return EFI_OUT_OF_RESOURCES;
>>> -  }
>>> -
>>> -  Volume->PartitionDescs =
>>> -    (UDF_PARTITION_DESCRIPTOR **)AllocateZeroPool (ExtentAd-
>>> >ExtentLength);
>>> -  if (Volume->PartitionDescs == NULL) {
>>> -    Status = EFI_OUT_OF_RESOURCES;
>>> -    goto Error_Alloc_Pds;
>>> -  }
>>> -
>>> -  Buffer = AllocateZeroPool (BlockSize);
>>> +  Buffer = AllocateZeroPool ((UINTN)BlockSize);
>>>    if (Buffer == NULL) {
>>> -    Status = EFI_OUT_OF_RESOURCES;
>>> -    goto Error_Alloc_Buf;
>>> +    return EFI_OUT_OF_RESOURCES;
>>>    }
>>> 
>>> -  Volume->LogicalVolDescsNo  = 0;
>>> -  Volume->PartitionDescsNo   = 0;
>>> -
>>> -  while (StartingLsn <= EndingLsn) {
>>> -    Status = DiskIo->ReadDisk (
>>> -      DiskIo,
>>> +  //
>>> +  // The logical partition created by Partition driver is relative
>>to the main
>>> +  // VDS extent location, so we start the Main Volume Descriptor
>>Sequence at
>>> +  // LBA 0.
>>> +  //
>>> +  // We don't need to check again if we have valid Volume
>>Descriptors here
>>> since
>>> +  // Partition driver already did.
>>> +  //
>>> +  SeqStartBlock = 0;
>>> +  SeqEndBlock = SeqStartBlock + DivU64x32
>>((UINT64)ExtentAd->ExtentLength,
>>> +                                           BlockSize); 
>StopSequence 
>>> + = FALSE;  for (; SeqStartBlock < SeqEndBlock && !StopSequence;
>>SeqStartBlock++) {
>>> +    //
>>> +    // Read disk block
>>> +    //
>>> +    Status = BlockIo->ReadBlocks (
>>> +      BlockIo,
>>>        BlockIo->Media->MediaId,
>>> -      MultU64x32 (StartingLsn, BlockSize),
>>> +      SeqStartBlock,
>>>        BlockSize,
>>>        Buffer
>>>        );
>>>      if (EFI_ERROR (Status)) {
>>> -      goto Error_Read_Disk_Blk;
>>> +      goto Out_Free;
>>>      }
>>> 
>>> -    if (IS_TD (Buffer)) {
>>> +    DescriptorTag = Buffer;
>>> +
>>> +    switch (UDF_TAG_ID (DescriptorTag)) {
>>> +    case UdfPartitionDescriptor:
>>>        //
>>> -      // Found a Terminating Descriptor. Stop the sequence then.
>>> +      // Save Partition Descriptor
>>>        //
>>> +      CopyMem (&Volume->PartitionDesc, Buffer, sizeof (Volume-
>>> >PartitionDesc));
>>>        break;
>>> -    }
>>> 
>>> -    if (IS_LVD (Buffer)) {
>>> +    case UdfLogicalVolumeDescriptor:
>>>        //
>>> -      // Found a Logical Volume Descriptor.
>>> +      // Save Logical Volume Descriptor
>>>        //
>>> -      LogicalVolDesc =
>>> -        (UDF_LOGICAL_VOLUME_DESCRIPTOR *)
>>> -        AllocateZeroPool (sizeof (UDF_LOGICAL_VOLUME_DESCRIPTOR));
>>> -      if (LogicalVolDesc == NULL) {
>>> -        Status = EFI_OUT_OF_RESOURCES;
>>> -        goto Error_Alloc_Lvd;
>>> -      }
>>> +      CopyMem (&Volume->LogicalVolDesc, Buffer, sizeof (Volume-
>>> >LogicalVolDesc));
>>> +      break;
>>> 
>>> -      CopyMem ((VOID *)LogicalVolDesc, Buffer,
>>> -               sizeof (UDF_LOGICAL_VOLUME_DESCRIPTOR));
>>> -      Volume->LogicalVolDescs[Volume->LogicalVolDescsNo++] =
>>> LogicalVolDesc;
>>> -    } else if (IS_PD (Buffer)) {
>>> -      //
>>> -      // Found a Partition Descriptor.
>>> -      //
>>> -      PartitionDesc =
>>> -        (UDF_PARTITION_DESCRIPTOR *)
>>> -        AllocateZeroPool (sizeof (UDF_PARTITION_DESCRIPTOR));
>>> -      if (PartitionDesc == NULL) {
>>> -        Status = EFI_OUT_OF_RESOURCES;
>>> -        goto Error_Alloc_Pd;
>>> -      }
>>> +    case UdfTerminatingDescriptor:
>>> +      StopSequence = TRUE;
>>> +      break;
>>> 
>>> -      CopyMem ((VOID *)PartitionDesc, Buffer,
>>> -               sizeof (UDF_PARTITION_DESCRIPTOR));
>>> -      Volume->PartitionDescs[Volume->PartitionDescsNo++] =
>>PartitionDesc;
>>> +    default:
>>> +      ;
>>>      }
>>> -
>>> -    StartingLsn++;
>>>    }
>>> 
>>>    //
>>> -  // When an UDF volume (revision 2.00 or higher) contains a File
>>Entry rather
>>> -  // than an Extended File Entry (which is not recommended as per
>>spec), we
>>> need
>>> -  // to make sure the size of a FE will be _at least_ 2048
>>> -  // (UDF_LOGICAL_SECTOR_SIZE) bytes long to keep backward
>>compatibility.
>>> +  // Determine FE (File Entry) size
>>>    //
>>> -  LogicalBlockSize = LV_BLOCK_SIZE (Volume, UDF_DEFAULT_LV_NUM);
>>> +  LogicalBlockSize = Volume->LogicalVolDesc.LogicalBlockSize;
>>>    if (LogicalBlockSize >= UDF_LOGICAL_SECTOR_SIZE) {
>>> -    Volume->FileEntrySize = LogicalBlockSize;
>>> +    Volume->FileEntrySize = (UINTN)LogicalBlockSize;
>>>    } else {
>>>      Volume->FileEntrySize = UDF_LOGICAL_SECTOR_SIZE;
>>>    }
>>> 
>>> -  FreePool (Buffer);
>>> +  Status = EFI_SUCCESS;
>>> 
>>> -  return EFI_SUCCESS;
>>> -
>>> -Error_Alloc_Pd:
>>> -Error_Alloc_Lvd:
>>> -  for (Index = 0; Index < Volume->PartitionDescsNo; Index++) {
>>> -    FreePool ((VOID *)Volume->PartitionDescs[Index]);
>>> -  }
>>> -
>>> -  for (Index = 0; Index < Volume->LogicalVolDescsNo; Index++) {
>>> -    FreePool ((VOID *)Volume->LogicalVolDescs[Index]);
>>> -  }
>>> -
>>> -Error_Read_Disk_Blk:
>>> +Out_Free:
>>> +  //
>>> +  // Free block read buffer
>>> +  //
>>>    FreePool (Buffer);
>>> 
>>> -Error_Alloc_Buf:
>>> -  FreePool ((VOID *)Volume->PartitionDescs);
>>> -  Volume->PartitionDescs = NULL;
>>> -
>>> -Error_Alloc_Pds:
>>> -  FreePool ((VOID *)Volume->LogicalVolDescs);
>>> -  Volume->LogicalVolDescs = NULL;
>>> -
>>>    return Status;
>>>  }
>>> 
>>> @@ -262,48 +216,53 @@ GetPdFromLongAd (
>>>    )
>>>  {
>>>    UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;
>>> -  UINTN                          Index;
>>> -  UDF_PARTITION_DESCRIPTOR       *PartitionDesc;
>>>    UINT16                         PartitionNum;
>>> 
>>> -  LogicalVolDesc = Volume->LogicalVolDescs[UDF_DEFAULT_LV_NUM];
>>> +  LogicalVolDesc = &Volume->LogicalVolDesc;
>>> 
>>> -  switch (LV_UDF_REVISION (LogicalVolDesc)) {
>>> +  switch (UDF_LVD_REVISION (LogicalVolDesc)) {
>>>    case 0x0102:
>>> +  case 0x0150:
>>> +  case 0x0200:
>>> +  case 0x0201:
>>> +  case 0x0250:
>>> +  case 0x0260:
>>>      //
>>> -    // As per UDF 1.02 specification:
>>> +    // UDF 1.02 specification:
>>>      //
>>>      // There shall be exactly one prevailing Logical Volume
>>Descriptor recorded
>>>      // per Volume Set. The Partition Maps field shall contain only
>>Type 1
>>>      // Partition Maps.
>>>      //
>>> -    PartitionNum = *(UINT16
>>*)((UINTN)&LogicalVolDesc->PartitionMaps[4]);
>>> -    break;
>>> -  case 0x0150:
>>> +    // UDF 1.50 through 2.60 specs say:
>>>      //
>>> -    // Ensure Type 1 Partition map. Other types aren't supported in
>>this
>>> -    // implementation.
>>> +    // For the purpose of interchange partition maps shall be
>>limited to
>>> +    // Partition Map type 1, except type 2 maps as described in the
>>document.
>>> +    //
>>> +    // NOTE: Only one Type 1 (Physical) Partition is supported. It
>>has been
>>> +    // checked already in Partition driver for existence of a
>single
>>Type 1
>>> +    // Partition map, so we don't have to double check here.
>>> +    //
>>> +    // Partition reference number can also be retrieved from
>>> +    // LongAd->ExtentLocation.PartitionReferenceNumber, however the
>>spec
>>> says
>>> +    // it may be 0, so let's not rely on it.
>>>      //
>>> -    if (LogicalVolDesc->PartitionMaps[0] != 1 ||
>>> -        LogicalVolDesc->PartitionMaps[1] != 6) {
>>> -      return NULL;
>>> -    }
>>>      PartitionNum = *(UINT16
>>*)((UINTN)&LogicalVolDesc->PartitionMaps[4]);
>>>      break;
>>> -  case 0x0260:
>>> +
>>> +  default:
>>>      //
>>> -    // Fall through.
>>> +    // Unsupported UDF revision
>>>      //
>>> -  default:
>>> -    PartitionNum = LongAd->ExtentLocation.PartitionReferenceNumber;
>>> -    break;
>>> +    return NULL;
>>>    }
>>> 
>>> -  

-- 
Sent from my Android device with K-9 Mail. Please excuse my brevity.
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Re: [edk2] [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix creation of UDF logical partition
Posted by Paulo Alcantara 7 years, 3 months ago
On Thu, Sep 21, 2017 at 10:52 AM, Paulo Alcantara <pcacjr@zytor.com> wrote:
>
>
> On September 21, 2017 10:47:07 AM GMT-03:00, "Zeng, Star" <star.zeng@intel.com> wrote:
>>Does it have functional impact?
>
> Nope. When Partition driver walks the partition detect routine table, it executes each routine and then checks for EFI_NO_MEDIA and EFI_MEDIA_CHANGED only. So, the child handle is installed and the EFI_NOT_FOUND is a no-op in that case.

BTW, I performed a quick test with UdfDxe enabled and disabled in OVMF
and the removal did not seem to break or change any behavior.

Thanks!
Paulo

>
> Thanks!
> Paulo
>
>>
>>Thanks,
>>Star
>>-----Original Message-----
>>From: Paulo Alcantara [mailto:pcacjr@zytor.com]
>>Sent: Thursday, September 21, 2017 9:29 PM
>>To: Wu, Hao A <hao.a.wu@intel.com>; edk2-devel@lists.01.org
>>Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Laszlo Ersek <lersek@redhat.com>;
>>Dong, Eric <eric.dong@intel.com>; Zeng, Star <star.zeng@intel.com>
>>Subject: RE: [edk2] [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix
>>creation of UDF logical partition
>>
>>
>>
>>On September 21, 2017 9:44:10 AM GMT-03:00, "Wu, Hao A"
>><hao.a.wu@intel.com> wrote:
>>>One small comment, within function PartitionInstallUdfChildHandles():
>>>
>>>  ...
>>>  //
>>>  // Install partition child handle for UDF file system
>>>  //
>>>  Status = PartitionInstallChildHandle (
>>>    ...
>>>    );
>>>if (!EFI_ERROR (Status)) {  <----- Is this a typo? "if (EFI_ERROR
>>>(Status)) {"
>>>    Status = EFI_NOT_FOUND;
>>>  }
>>
>>Yes, it is. Good catch! Could you please fix that for me by removing
>>the if condition? Otherwise I can send a v4 later with that.
>>
>>Thanks!
>>Paulo
>>
>>>
>>>
>>>Best Regards,
>>>Hao Wu
>>>
>>>
>>>> -----Original Message-----
>>>> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf
>>>Of Paulo
>>>> Alcantara
>>>> Sent: Thursday, September 21, 2017 2:16 AM
>>>> To: edk2-devel@lists.01.org
>>>> Cc: Ni, Ruiyu; Laszlo Ersek; Dong, Eric; Zeng, Star
>>>> Subject: [edk2] [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix
>>>creation of
>>>> UDF logical partition
>>>>
>>>> Do not reserve entire block device size for an UDF file system -
>>>> instead, reserve the appropriate space (UDF logical volume space)
>>for
>>>> it.
>>>>
>>>> Additionally, only create a logical partition for UDF logical
>>volumes
>>>> that are currently supported by EDK2 UDF file system implementation.
>>>For
>>>> instance, an UDF volume with a single LVD and a single Physical
>>(Type
>>>1)
>>>> Partition will be supported.
>>>>
>>>> Cc: Eric Dong <eric.dong@intel.com>
>>>> Cc: Ruiyu Ni <ruiyu.ni@intel.com>
>>>> Cc: Star Zeng <star.zeng@intel.com>
>>>> Cc: Laszlo Ersek <lersek@redhat.com>
>>>> Reported-by: Ruiyu Ni <ruiyu.ni@intel.com>
>>>> Contributed-under: TianoCore Contribution Agreement 1.1
>>>> Signed-off-by: Paulo Alcantara <pcacjr@zytor.com>
>>>> ---
>>>>  MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c            | 363
>>>++++++++++--
>>>>  MdeModulePkg/Universal/Disk/UdfDxe/File.c                 |  16 +-
>>>>  MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c | 627
>>>> ++++++++------------
>>>>  MdeModulePkg/Universal/Disk/UdfDxe/Udf.c                  |   7 -
>>>>  MdeModulePkg/Universal/Disk/UdfDxe/Udf.h                  | 158
>>>++---
>>>>  5 files changed, 606 insertions(+), 565 deletions(-)
>>>>
>>>> diff --git a/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
>>>> b/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
>>>> index 609f56cef6..572ba7a81a 100644
>>>> --- a/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
>>>> +++ b/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
>>>> @@ -64,11 +64,12 @@ FindAnchorVolumeDescriptorPointer (
>>>>    OUT  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint
>>>>    )
>>>>  {
>>>> -  EFI_STATUS  Status;
>>>> -  UINT32      BlockSize;
>>>> -  EFI_LBA     EndLBA;
>>>> -  EFI_LBA     DescriptorLBAs[4];
>>>> -  UINTN       Index;
>>>> +  EFI_STATUS          Status;
>>>> +  UINT32              BlockSize;
>>>> +  EFI_LBA             EndLBA;
>>>> +  EFI_LBA             DescriptorLBAs[4];
>>>> +  UINTN               Index;
>>>> +  UDF_DESCRIPTOR_TAG  *DescriptorTag;
>>>>
>>>>    BlockSize = BlockIo->Media->BlockSize;
>>>>    EndLBA = BlockIo->Media->LastBlock; @@ -88,10 +89,13 @@
>>>> FindAnchorVolumeDescriptorPointer (
>>>>      if (EFI_ERROR (Status)) {
>>>>        return Status;
>>>>      }
>>>> +
>>>> +    DescriptorTag = &AnchorPoint->DescriptorTag;
>>>> +
>>>>      //
>>>>      // Check if read LBA has a valid AVDP descriptor.
>>>>      //
>>>> -    if (IS_AVDP (AnchorPoint)) {
>>>> +    if (DescriptorTag->TagIdentifier ==
>>>UdfAnchorVolumeDescriptorPointer) {
>>>>        return EFI_SUCCESS;
>>>>      }
>>>>    }
>>>> @@ -102,23 +106,18 @@ FindAnchorVolumeDescriptorPointer (  }
>>>>
>>>>  /**
>>>> -  Check if block device supports a valid UDF file system as
>>>specified by OSTA
>>>> -  Universal Disk Format Specification 2.60.
>>>> +  Find UDF volume identifiers in a Volume Recognition Sequence.
>>>>
>>>> -  @param[in]   BlockIo  BlockIo interface.
>>>> -  @param[in]   DiskIo   DiskIo interface.
>>>> +  @param[in]  BlockIo             BlockIo interface.
>>>> +  @param[in]  DiskIo              DiskIo interface.
>>>>
>>>> -  @retval EFI_SUCCESS          UDF file system found.
>>>> -  @retval EFI_UNSUPPORTED      UDF file system not found.
>>>> -  @retval EFI_NO_MEDIA         The device has no media.
>>>> -  @retval EFI_DEVICE_ERROR     The device reported an error.
>>>> -  @retval EFI_VOLUME_CORRUPTED The file system structures are
>>>corrupted.
>>>> -  @retval EFI_OUT_OF_RESOURCES The scan was not successful due to
>>>lack of
>>>> -                               resources.
>>>> +  @retval EFI_SUCCESS             UDF volume identifiers were
>>found.
>>>> +  @retval EFI_NOT_FOUND           UDF volume identifiers were not
>>>found.
>>>> +  @retval other                   Failed to perform disk I/O.
>>>>
>>>>  **/
>>>>  EFI_STATUS
>>>> -SupportUdfFileSystem (
>>>> +FindUdfVolumeIdentifiers (
>>>>    IN EFI_BLOCK_IO_PROTOCOL  *BlockIo,
>>>>    IN EFI_DISK_IO_PROTOCOL   *DiskIo
>>>>    )
>>>> @@ -128,7 +127,6 @@ SupportUdfFileSystem (
>>>>    UINT64                                EndDiskOffset;
>>>>    CDROM_VOLUME_DESCRIPTOR               VolDescriptor;
>>>>    CDROM_VOLUME_DESCRIPTOR               TerminatingVolDescriptor;
>>>> -  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  AnchorPoint;
>>>>
>>>>    ZeroMem ((VOID *)&TerminatingVolDescriptor, sizeof
>>>> (CDROM_VOLUME_DESCRIPTOR));
>>>>
>>>> @@ -167,7 +165,7 @@ SupportUdfFileSystem (
>>>>          (CompareMem ((VOID *)&VolDescriptor,
>>>>                       (VOID *)&TerminatingVolDescriptor,
>>>>                       sizeof (CDROM_VOLUME_DESCRIPTOR)) == 0)) {
>>>> -      return EFI_UNSUPPORTED;
>>>> +      return EFI_NOT_FOUND;
>>>>      }
>>>>    }
>>>>
>>>> @@ -176,7 +174,7 @@ SupportUdfFileSystem (
>>>>    //
>>>>    Offset += UDF_LOGICAL_SECTOR_SIZE;
>>>>    if (Offset >= EndDiskOffset) {
>>>> -    return EFI_UNSUPPORTED;
>>>> +    return EFI_NOT_FOUND;
>>>>    }
>>>>
>>>>    Status = DiskIo->ReadDisk (
>>>> @@ -196,7 +194,7 @@ SupportUdfFileSystem (
>>>>        (CompareMem ((VOID *)VolDescriptor.Unknown.Id,
>>>>                     (VOID *)UDF_NSR3_IDENTIFIER,
>>>>                     sizeof (VolDescriptor.Unknown.Id)) != 0)) {
>>>> -    return EFI_UNSUPPORTED;
>>>> +    return EFI_NOT_FOUND;
>>>>    }
>>>>
>>>>    //
>>>> @@ -204,7 +202,7 @@ SupportUdfFileSystem (
>>>>    //
>>>>    Offset += UDF_LOGICAL_SECTOR_SIZE;
>>>>    if (Offset >= EndDiskOffset) {
>>>> -    return EFI_UNSUPPORTED;
>>>> +    return EFI_NOT_FOUND;
>>>>    }
>>>>
>>>>    Status = DiskIo->ReadDisk (
>>>> @@ -221,15 +219,291 @@ SupportUdfFileSystem (
>>>>    if (CompareMem ((VOID *)VolDescriptor.Unknown.Id,
>>>>                    (VOID *)UDF_TEA_IDENTIFIER,
>>>>                    sizeof (VolDescriptor.Unknown.Id)) != 0) {
>>>> -    return EFI_UNSUPPORTED;
>>>> +    return EFI_NOT_FOUND;
>>>> +  }
>>>> +
>>>> +  return EFI_SUCCESS;
>>>> +}
>>>> +
>>>> +/**
>>>> +  Check if Logical Volume Descriptor is supported by current EDK2
>>>UDF file
>>>> +  system implementation.
>>>> +
>>>> +  @param[in]  LogicalVolDesc  Logical Volume Descriptor pointer.
>>>> +
>>>> +  @retval TRUE                Logical Volume Descriptor is
>>>supported.
>>>> +  @retval FALSE               Logical Volume Descriptor is not
>>>supported.
>>>> +
>>>> +**/
>>>> +BOOLEAN
>>>> +IsLogicalVolumeDescriptorSupported (
>>>> +  UDF_LOGICAL_VOLUME_DESCRIPTOR *LogicalVolDesc
>>>> +  )
>>>> +{
>>>> +  //
>>>> +  // Check for a valid UDF revision range
>>>> +  //
>>>> +  switch (UDF_LVD_REVISION (LogicalVolDesc)) {
>>>> +  case 0x0102:
>>>> +  case 0x0150:
>>>> +  case 0x0200:
>>>> +  case 0x0201:
>>>> +  case 0x0250:
>>>> +  case 0x0260:
>>>> +    break;
>>>> +  default:
>>>> +    return FALSE;
>>>> +  }
>>>> +
>>>> +  //
>>>> +  // Check for a single Partition Map  //  if
>>>> + (LogicalVolDesc->NumberOfPartitionMaps > 1) {
>>>> +    return FALSE;
>>>> +  }
>>>> +  //
>>>> +  // UDF 1.02 revision supports only Type 1 (Physical) partitions,
>>>but
>>>> +  // let's check it any way.
>>>> +  //
>>>> +  // PartitionMap[0] -> type
>>>> +  // PartitionMap[1] -> length (in bytes)  //  if
>>>> + (LogicalVolDesc->PartitionMaps[0] != 1 ||
>>>> +      LogicalVolDesc->PartitionMaps[1] != 6) {
>>>> +    return FALSE;
>>>> +  }
>>>> +
>>>> +  return TRUE;
>>>> +}
>>>> +
>>>> +/**
>>>> +  Find UDF logical volume location and whether it is supported by
>>>current EDK2
>>>> +  UDF file system implementation.
>>>> +
>>>> +  @param[in]  BlockIo             BlockIo interface.
>>>> +  @param[in]  DiskIo              DiskIo interface.
>>>> +  @param[in]  AnchorPoint         Anchor volume descriptor pointer.
>>>> +  @param[out] MainVdsStartBlock   Main VDS starting block number.
>>>> +  @param[out] MainVdsEndBlock     Main VDS ending block number.
>>>> +
>>>> +  @retval EFI_SUCCESS             UDF logical volume was found.
>>>> +  @retval EFI_VOLUME_CORRUPTED    UDF file system structures are
>>>> corrupted.
>>>> +  @retval EFI_UNSUPPORTED         UDF logical volume is not
>>>supported.
>>>> +  @retval other                   Failed to perform disk I/O.
>>>> +
>>>> +**/
>>>> +EFI_STATUS
>>>> +FindLogicalVolumeLocation (
>>>> +  IN   EFI_BLOCK_IO_PROTOCOL                 *BlockIo,
>>>> +  IN   EFI_DISK_IO_PROTOCOL                  *DiskIo,
>>>> +  IN   UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint,
>>>> +  OUT  UINT64                                *MainVdsStartBlock,
>>>> +  OUT  UINT64                                *MainVdsEndBlock
>>>> +  )
>>>> +{
>>>> +  EFI_STATUS                     Status;
>>>> +  UINT32                         BlockSize;
>>>> +  EFI_LBA                        LastBlock;
>>>> +  UDF_EXTENT_AD                  *ExtentAd;
>>>> +  UINT64                         SeqBlocksNum;
>>>> +  UINT64                         SeqStartBlock;
>>>> +  UINT64                         GuardMainVdsStartBlock;
>>>> +  VOID                           *Buffer;
>>>> +  UINT64                         SeqEndBlock;
>>>> +  BOOLEAN                        StopSequence;
>>>> +  UINTN                          LvdsCount;
>>>> +  UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;
>>>> +  UDF_DESCRIPTOR_TAG             *DescriptorTag;
>>>> +
>>>> +  BlockSize = BlockIo->Media->BlockSize;  LastBlock =
>>>> + BlockIo->Media->LastBlock;  ExtentAd =
>>>> + &AnchorPoint->MainVolumeDescriptorSequenceExtent;
>>>> +
>>>> +  //
>>>> +  // UDF 2.60, 2.2.3.1 struct MainVolumeDescriptorSequenceExtent
>>>> +  //
>>>> +  // The Main Volume Descriptor Sequence Extent shall have a
>>minimum
>>>length
>>>> of
>>>> +  // 16 logical sectors.
>>>> +  //
>>>> +  // Also make sure it does not exceed maximum number of blocks in
>>>the disk.
>>>> +  //
>>>> +  SeqBlocksNum = DivU64x32 ((UINT64)ExtentAd->ExtentLength,
>>>BlockSize);
>>>> +  if (SeqBlocksNum < 16 || (EFI_LBA)SeqBlocksNum > LastBlock + 1) {
>>>> +    return EFI_VOLUME_CORRUPTED;
>>>> +  }
>>>> +
>>>> +  //
>>>> +  // Check for valid Volume Descriptor Sequence starting block
>>>number
>>>> +  //
>>>> +  SeqStartBlock = (UINT64)ExtentAd->ExtentLocation;  if
>>>> + (SeqStartBlock > LastBlock ||
>>>> +      SeqStartBlock + SeqBlocksNum - 1 > LastBlock) {
>>>> +    return EFI_VOLUME_CORRUPTED;
>>>>    }
>>>>
>>>> +  GuardMainVdsStartBlock = SeqStartBlock;
>>>> +
>>>> +  //
>>>> +  // Allocate buffer for reading disk blocks  //  Buffer =
>>>> + AllocateZeroPool ((UINTN)BlockSize);  if (Buffer == NULL) {
>>>> +    return EFI_OUT_OF_RESOURCES;
>>>> +  }
>>>> +
>>>> +  SeqEndBlock = SeqStartBlock + SeqBlocksNum;  StopSequence =
>>FALSE;
>>>> + LvdsCount = 0;  Status = EFI_VOLUME_CORRUPTED;  //  // Start Main
>>>> + Volume Descriptor Sequence  //  for (; SeqStartBlock < SeqEndBlock
>>
>>>> + && !StopSequence;
>>>SeqStartBlock++) {
>>>> +    //
>>>> +    // Read disk block
>>>> +    //
>>>> +    Status = BlockIo->ReadBlocks (
>>>> +      BlockIo,
>>>> +      BlockIo->Media->MediaId,
>>>> +      SeqStartBlock,
>>>> +      BlockSize,
>>>> +      Buffer
>>>> +      );
>>>> +    if (EFI_ERROR (Status)) {
>>>> +      goto Out_Free;
>>>> +    }
>>>> +
>>>> +    DescriptorTag = Buffer;
>>>> +
>>>> +    //
>>>> +    // ECMA 167, 8.4.1 Contents of a Volume Descriptor Sequence
>>>> +    //
>>>> +    // - A Volume Descriptor Sequence shall contain one or more
>>>Primary
>>>> Volume
>>>> +    //   Descriptors.
>>>> +    // - A Volume Descriptor Sequence shall contain zero or more
>>>> Implementation
>>>> +    //   Use Volume Descriptors.
>>>> +    // - A Volume Descriptor Sequence shall contain zero or more
>>>Partition
>>>> +    //   Descriptors.
>>>> +    // - A Volume Descriptor Sequence shall contain zero or more
>>>Logical
>>>> Volume
>>>> +    //   Descriptors.
>>>> +    // - A Volume Descriptor Sequence shall contain zero or more
>>>Unallocated
>>>> +    //   Space Descriptors.
>>>> +    //
>>>> +    switch (UDF_TAG_ID (DescriptorTag)) {
>>>> +    case UdfPrimaryVolumeDescriptor:
>>>> +    case UdfImplemenationUseVolumeDescriptor:
>>>> +    case UdfPartitionDescriptor:
>>>> +    case UdfUnallocatedSpaceDescriptor:
>>>> +      break;
>>>> +
>>>> +    case UdfLogicalVolumeDescriptor:
>>>> +      LogicalVolDesc = Buffer;
>>>> +
>>>> +      //
>>>> +      // Check for existence of a single LVD and whether it is
>>>supported by
>>>> +      // current EDK2 UDF file system implementation.
>>>> +      //
>>>> +      if (++LvdsCount > 1 ||
>>>> +          !IsLogicalVolumeDescriptorSupported (LogicalVolDesc)) {
>>>> +        Status = EFI_UNSUPPORTED;
>>>> +        StopSequence = TRUE;
>>>> +      }
>>>> +
>>>> +      break;
>>>> +
>>>> +    case UdfTerminatingDescriptor:
>>>> +      //
>>>> +      // Stop the sequence when we find a Terminating Descriptor
>>>> +      // (aka Unallocated Sector), se we don't have to walk all the
>>>unallocated
>>>> +      // area unnecessarily.
>>>> +      //
>>>> +      StopSequence = TRUE;
>>>> +      break;
>>>> +
>>>> +    default:
>>>> +      //
>>>> +      // An invalid Volume Descriptor has been found in the
>>sequece.
>>>Volume is
>>>> +      // corrupted.
>>>> +      //
>>>> +      Status = EFI_VOLUME_CORRUPTED;
>>>> +      goto Out_Free;
>>>> +    }
>>>> +  }
>>>> +
>>>> +  //
>>>> +  // Check if LVD was found
>>>> +  //
>>>> +  if (!EFI_ERROR (Status) && LvdsCount == 1) {
>>>> +    *MainVdsStartBlock = GuardMainVdsStartBlock;
>>>> +    //
>>>> +    // We do not need to read either LVD or PD descriptors to know
>>>the last
>>>> +    // valid block in the found UDF file system. It's already
>>>LastBlock.
>>>> +    //
>>>> +    *MainVdsEndBlock = LastBlock;
>>>> +
>>>> +    Status = EFI_SUCCESS;
>>>> +  }
>>>> +
>>>> +Out_Free:
>>>> +  //
>>>> +  // Free block read buffer
>>>> +  //
>>>> +  FreePool (Buffer);
>>>> +
>>>> +  return Status;
>>>> +}
>>>> +
>>>> +/**
>>>> +  Find a supported UDF file system in block device.
>>>> +
>>>> +  @param[in]  BlockIo             BlockIo interface.
>>>> +  @param[in]  DiskIo              DiskIo interface.
>>>> +  @param[out] StartingLBA         UDF file system starting LBA.
>>>> +  @param[out] EndingLBA           UDF file system starting LBA.
>>>> +
>>>> +  @retval EFI_SUCCESS             UDF file system was found.
>>>> +  @retval other                   UDF file system was not found.
>>>> +
>>>> +**/
>>>> +EFI_STATUS
>>>> +FindUdfFileSystem (
>>>> +  IN EFI_BLOCK_IO_PROTOCOL  *BlockIo,
>>>> +  IN EFI_DISK_IO_PROTOCOL   *DiskIo,
>>>> +  OUT EFI_LBA               *StartingLBA,
>>>> +  OUT EFI_LBA               *EndingLBA
>>>> +  )
>>>> +{
>>>> +  EFI_STATUS Status;
>>>> +  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  AnchorPoint;
>>>> +
>>>> +  //
>>>> +  // Find UDF volume identifiers
>>>> +  //
>>>> +  Status = FindUdfVolumeIdentifiers (BlockIo, DiskIo);  if
>>>> + (EFI_ERROR (Status)) {
>>>> +    return Status;
>>>> +  }
>>>> +
>>>> +  //
>>>> +  // Find Anchor Volume Descriptor Pointer  //
>>>>    Status = FindAnchorVolumeDescriptorPointer (BlockIo, DiskIo,
>>>&AnchorPoint);
>>>>    if (EFI_ERROR (Status)) {
>>>> -    return EFI_UNSUPPORTED;
>>>> +    return Status;
>>>>    }
>>>>
>>>> -  return EFI_SUCCESS;
>>>> +  //
>>>> +  // Find Logical Volume location
>>>> +  //
>>>> +  Status = FindLogicalVolumeLocation (
>>>> +    BlockIo,
>>>> +    DiskIo,
>>>> +    &AnchorPoint,
>>>> +    (UINT64 *)StartingLBA,
>>>> +    (UINT64 *)EndingLBA
>>>> +    );
>>>> +
>>>> +  return Status;
>>>>  }
>>>>
>>>>  /**
>>>> @@ -263,9 +537,9 @@ PartitionInstallUdfChildHandles (
>>>>    UINT32                       RemainderByMediaBlockSize;
>>>>    EFI_STATUS                   Status;
>>>>    EFI_BLOCK_IO_MEDIA           *Media;
>>>> -  EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode;
>>>> -  EFI_GUID                     *VendorDefinedGuid;
>>>>    EFI_PARTITION_INFO_PROTOCOL  PartitionInfo;
>>>> +  EFI_LBA                      StartingLBA;
>>>> +  EFI_LBA                      EndingLBA;
>>>>
>>>>    Media = BlockIo->Media;
>>>>
>>>> @@ -281,35 +555,10 @@ PartitionInstallUdfChildHandles (
>>>>      return EFI_NOT_FOUND;
>>>>    }
>>>>
>>>> -  DevicePathNode = DevicePath;
>>>> -  while (!IsDevicePathEnd (DevicePathNode)) {
>>>> -    //
>>>> -    // Do not allow checking for UDF file systems in CDROM "El
>>>Torito"
>>>> -    // partitions, and skip duplicate installation of UDF file
>>>system child
>>>> -    // nodes.
>>>> -    //
>>>> -    if (DevicePathType (DevicePathNode) == MEDIA_DEVICE_PATH) {
>>>> -      if (DevicePathSubType (DevicePathNode) == MEDIA_CDROM_DP) {
>>>> -        return EFI_NOT_FOUND;
>>>> -      }
>>>> -      if (DevicePathSubType (DevicePathNode) == MEDIA_VENDOR_DP) {
>>>> -        VendorDefinedGuid = (EFI_GUID *)((UINTN)DevicePathNode +
>>>> -                                         OFFSET_OF
>>>(VENDOR_DEVICE_PATH, Guid));
>>>> -        if (CompareGuid (VendorDefinedGuid, &gUdfDevPathGuid)) {
>>>> -          return EFI_NOT_FOUND;
>>>> -        }
>>>> -      }
>>>> -    }
>>>> -    //
>>>> -    // Try next device path node
>>>> -    //
>>>> -    DevicePathNode = NextDevicePathNode (DevicePathNode);
>>>> -  }
>>>> -
>>>>    //
>>>> -  // Check if block device supports an UDF file system
>>>> +  // Search for an UDF file system on block device
>>>>    //
>>>> -  Status = SupportUdfFileSystem (BlockIo, DiskIo);
>>>> +  Status = FindUdfFileSystem (BlockIo, DiskIo, &StartingLBA,
>>>&EndingLBA);
>>>>    if (EFI_ERROR (Status)) {
>>>>      return EFI_NOT_FOUND;
>>>>    }
>>>> @@ -334,8 +583,8 @@ PartitionInstallUdfChildHandles (
>>>>      DevicePath,
>>>>      (EFI_DEVICE_PATH_PROTOCOL *)&gUdfDevicePath,
>>>>      &PartitionInfo,
>>>> -    0,
>>>> -    Media->LastBlock,
>>>> +    StartingLBA,
>>>> +    EndingLBA,
>>>>      Media->BlockSize
>>>>      );
>>>>    if (!EFI_ERROR (Status)) {
>>>> diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/File.c
>>>> b/MdeModulePkg/Universal/Disk/UdfDxe/File.c
>>>> index 625f2c5637..6f07bf2066 100644
>>>> --- a/MdeModulePkg/Universal/Disk/UdfDxe/File.c
>>>> +++ b/MdeModulePkg/Universal/Disk/UdfDxe/File.c
>>>> @@ -131,7 +131,6 @@ Error_Alloc_Priv_File_Data:
>>>>    CleanupFileInformation (&PrivFsData->Root);
>>>>
>>>>  Error_Find_Root_Dir:
>>>> -  CleanupVolumeInformation (&PrivFsData->Volume);
>>>>
>>>>  Error_Read_Udf_Volume:
>>>>  Error_Invalid_Params:
>>>> @@ -429,7 +428,7 @@ UdfRead (
>>>>      }
>>>>      ASSERT (NewFileEntryData != NULL);
>>>>
>>>> -    if (IS_FE_SYMLINK (NewFileEntryData)) {
>>>> +    if (FE_ICB_FILE_TYPE (NewFileEntryData) == UdfFileEntrySymlink)
>>>{
>>>>        Status = ResolveSymlink (
>>>>          BlockIo,
>>>>          DiskIo,
>>>> @@ -529,7 +528,6 @@ UdfClose (
>>>>    EFI_TPL                     OldTpl;
>>>>    EFI_STATUS                  Status;
>>>>    PRIVATE_UDF_FILE_DATA       *PrivFileData;
>>>> -  PRIVATE_UDF_SIMPLE_FS_DATA  *PrivFsData;
>>>>
>>>>    OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
>>>>
>>>> @@ -542,8 +540,6 @@ UdfClose (
>>>>
>>>>    PrivFileData = PRIVATE_UDF_FILE_DATA_FROM_THIS (This);
>>>>
>>>> -  PrivFsData = PRIVATE_UDF_SIMPLE_FS_DATA_FROM_THIS (PrivFileData-
>>>> >SimpleFs);
>>>> -
>>>>    if (!PrivFileData->IsRootDirectory) {
>>>>      CleanupFileInformation (&PrivFileData->File);
>>>>
>>>> @@ -552,10 +548,6 @@ UdfClose (
>>>>      }
>>>>    }
>>>>
>>>> -  if (--PrivFsData->OpenFiles == 0) {
>>>> -    CleanupVolumeInformation (&PrivFsData->Volume);
>>>> -  }
>>>> -
>>>>    FreePool ((VOID *)PrivFileData);
>>>>
>>>>  Exit:
>>>> @@ -652,7 +644,7 @@ UdfGetPosition (
>>>>    // As per UEFI spec, if the file handle is a directory, then the
>>>current file
>>>>    // position has no meaning and the operation is not supported.
>>>>    //
>>>> -  if (IS_FID_DIRECTORY_FILE
>>>(&PrivFileData->File.FileIdentifierDesc)) {
>>>> +  if (IS_FID_DIRECTORY_FILE
>>(PrivFileData->File.FileIdentifierDesc))
>>>{
>>>>      return  EFI_UNSUPPORTED;
>>>>    }
>>>>
>>>> @@ -788,7 +780,7 @@ UdfGetInfo (
>>>>    } else if (CompareGuid (InformationType,
>>&gEfiFileSystemInfoGuid))
>>>{
>>>>      String = VolumeLabel;
>>>>
>>>> -    FileSetDesc = PrivFsData->Volume.FileSetDescs[0];
>>>> +    FileSetDesc = &PrivFsData->Volume.FileSetDesc;
>>>>
>>>>      OstaCompressed = &FileSetDesc->LogicalVolumeIdentifier[0];
>>>>
>>>> @@ -847,7 +839,7 @@ UdfGetInfo (
>>>>      FileSystemInfo->Size        = FileSystemInfoLength;
>>>>      FileSystemInfo->ReadOnly    = TRUE;
>>>>      FileSystemInfo->BlockSize   =
>>>> -      LV_BLOCK_SIZE (&PrivFsData->Volume, UDF_DEFAULT_LV_NUM);
>>>> +      PrivFsData->Volume.LogicalVolDesc.LogicalBlockSize;
>>>>      FileSystemInfo->VolumeSize  = VolumeSize;
>>>>      FileSystemInfo->FreeSpace   = FreeSpaceSize;
>>>>
>>>> diff --git
>>>a/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
>>>> b/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
>>>> index 5df267761f..62d817989f 100644
>>>> --- a/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
>>>> +++ b/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
>>>> @@ -38,11 +38,12 @@ FindAnchorVolumeDescriptorPointer (
>>>>    OUT  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint
>>>>    )
>>>>  {
>>>> -  EFI_STATUS  Status;
>>>> -  UINT32      BlockSize;
>>>> -  EFI_LBA     EndLBA;
>>>> -  EFI_LBA     DescriptorLBAs[4];
>>>> -  UINTN       Index;
>>>> +  EFI_STATUS          Status;
>>>> +  UINT32              BlockSize;
>>>> +  EFI_LBA             EndLBA;
>>>> +  EFI_LBA             DescriptorLBAs[4];
>>>> +  UINTN               Index;
>>>> +  UDF_DESCRIPTOR_TAG  *DescriptorTag;
>>>>
>>>>    BlockSize = BlockIo->Media->BlockSize;
>>>>    EndLBA = BlockIo->Media->LastBlock; @@ -62,10 +63,13 @@
>>>> FindAnchorVolumeDescriptorPointer (
>>>>      if (EFI_ERROR (Status)) {
>>>>        return Status;
>>>>      }
>>>> +
>>>> +    DescriptorTag = &AnchorPoint->DescriptorTag;
>>>> +
>>>>      //
>>>>      // Check if read LBA has a valid AVDP descriptor.
>>>>      //
>>>> -    if (IS_AVDP (AnchorPoint)) {
>>>> +    if (DescriptorTag->TagIdentifier ==
>>>UdfAnchorVolumeDescriptorPointer) {
>>>>        return EFI_SUCCESS;
>>>>      }
>>>>    }
>>>> @@ -99,148 +103,98 @@ StartMainVolumeDescriptorSequence (
>>>>    OUT  UDF_VOLUME_INFO                       *Volume
>>>>    )
>>>>  {
>>>> -  EFI_STATUS                     Status;
>>>> -  UINT32                         BlockSize;
>>>> -  UDF_EXTENT_AD                  *ExtentAd;
>>>> -  UINT64                         StartingLsn;
>>>> -  UINT64                         EndingLsn;
>>>> -  VOID                           *Buffer;
>>>> -  UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;
>>>> -  UDF_PARTITION_DESCRIPTOR       *PartitionDesc;
>>>> -  UINTN                          Index;
>>>> -  UINT32                         LogicalBlockSize;
>>>> +  EFI_STATUS            Status;
>>>> +  UINT32                BlockSize;
>>>> +  UDF_EXTENT_AD         *ExtentAd;
>>>> +  EFI_LBA               SeqStartBlock;
>>>> +  EFI_LBA               SeqEndBlock;
>>>> +  BOOLEAN               StopSequence;
>>>> +  VOID                  *Buffer;
>>>> +  UDF_DESCRIPTOR_TAG    *DescriptorTag;
>>>> +  UINT32                LogicalBlockSize;
>>>> +
>>>> +  BlockSize = BlockIo->Media->BlockSize;  ExtentAd =
>>>> + &AnchorPoint->MainVolumeDescriptorSequenceExtent;
>>>>
>>>>    //
>>>> -  // We've already found an ADVP on the volume. It contains the
>>>extent
>>>> -  // (MainVolumeDescriptorSequenceExtent) where the Main Volume
>>>> Descriptor
>>>> -  // Sequence starts. Therefore, we'll look for Logical Volume
>>>Descriptors and
>>>> -  // Partitions Descriptors and save them in memory, accordingly.
>>>> -  //
>>>> -  // Note also that each descriptor will be aligned on a block size
>>>(BlockSize)
>>>> -  // boundary, so we need to read one block at a time.
>>>> +  // Allocate buffer for reading disk blocks
>>>>    //
>>>> -  BlockSize    = BlockIo->Media->BlockSize;
>>>> -  ExtentAd     = &AnchorPoint->MainVolumeDescriptorSequenceExtent;
>>>> -  StartingLsn  = (UINT64)ExtentAd->ExtentLocation;
>>>> -  EndingLsn    = StartingLsn + DivU64x32 (
>>>> -
>>(UINT64)ExtentAd->ExtentLength,
>>>> -                                     BlockSize
>>>> -                                     );
>>>> -
>>>> -  Volume->LogicalVolDescs =
>>>> -    (UDF_LOGICAL_VOLUME_DESCRIPTOR **)AllocateZeroPool (ExtentAd-
>>>> >ExtentLength);
>>>> -  if (Volume->LogicalVolDescs == NULL) {
>>>> -    return EFI_OUT_OF_RESOURCES;
>>>> -  }
>>>> -
>>>> -  Volume->PartitionDescs =
>>>> -    (UDF_PARTITION_DESCRIPTOR **)AllocateZeroPool (ExtentAd-
>>>> >ExtentLength);
>>>> -  if (Volume->PartitionDescs == NULL) {
>>>> -    Status = EFI_OUT_OF_RESOURCES;
>>>> -    goto Error_Alloc_Pds;
>>>> -  }
>>>> -
>>>> -  Buffer = AllocateZeroPool (BlockSize);
>>>> +  Buffer = AllocateZeroPool ((UINTN)BlockSize);
>>>>    if (Buffer == NULL) {
>>>> -    Status = EFI_OUT_OF_RESOURCES;
>>>> -    goto Error_Alloc_Buf;
>>>> +    return EFI_OUT_OF_RESOURCES;
>>>>    }
>>>>
>>>> -  Volume->LogicalVolDescsNo  = 0;
>>>> -  Volume->PartitionDescsNo   = 0;
>>>> -
>>>> -  while (StartingLsn <= EndingLsn) {
>>>> -    Status = DiskIo->ReadDisk (
>>>> -      DiskIo,
>>>> +  //
>>>> +  // The logical partition created by Partition driver is relative
>>>to the main
>>>> +  // VDS extent location, so we start the Main Volume Descriptor
>>>Sequence at
>>>> +  // LBA 0.
>>>> +  //
>>>> +  // We don't need to check again if we have valid Volume
>>>Descriptors here
>>>> since
>>>> +  // Partition driver already did.
>>>> +  //
>>>> +  SeqStartBlock = 0;
>>>> +  SeqEndBlock = SeqStartBlock + DivU64x32
>>>((UINT64)ExtentAd->ExtentLength,
>>>> +                                           BlockSize);
>>StopSequence
>>>> + = FALSE;  for (; SeqStartBlock < SeqEndBlock && !StopSequence;
>>>SeqStartBlock++) {
>>>> +    //
>>>> +    // Read disk block
>>>> +    //
>>>> +    Status = BlockIo->ReadBlocks (
>>>> +      BlockIo,
>>>>        BlockIo->Media->MediaId,
>>>> -      MultU64x32 (StartingLsn, BlockSize),
>>>> +      SeqStartBlock,
>>>>        BlockSize,
>>>>        Buffer
>>>>        );
>>>>      if (EFI_ERROR (Status)) {
>>>> -      goto Error_Read_Disk_Blk;
>>>> +      goto Out_Free;
>>>>      }
>>>>
>>>> -    if (IS_TD (Buffer)) {
>>>> +    DescriptorTag = Buffer;
>>>> +
>>>> +    switch (UDF_TAG_ID (DescriptorTag)) {
>>>> +    case UdfPartitionDescriptor:
>>>>        //
>>>> -      // Found a Terminating Descriptor. Stop the sequence then.
>>>> +      // Save Partition Descriptor
>>>>        //
>>>> +      CopyMem (&Volume->PartitionDesc, Buffer, sizeof (Volume-
>>>> >PartitionDesc));
>>>>        break;
>>>> -    }
>>>>
>>>> -    if (IS_LVD (Buffer)) {
>>>> +    case UdfLogicalVolumeDescriptor:
>>>>        //
>>>> -      // Found a Logical Volume Descriptor.
>>>> +      // Save Logical Volume Descriptor
>>>>        //
>>>> -      LogicalVolDesc =
>>>> -        (UDF_LOGICAL_VOLUME_DESCRIPTOR *)
>>>> -        AllocateZeroPool (sizeof (UDF_LOGICAL_VOLUME_DESCRIPTOR));
>>>> -      if (LogicalVolDesc == NULL) {
>>>> -        Status = EFI_OUT_OF_RESOURCES;
>>>> -        goto Error_Alloc_Lvd;
>>>> -      }
>>>> +      CopyMem (&Volume->LogicalVolDesc, Buffer, sizeof (Volume-
>>>> >LogicalVolDesc));
>>>> +      break;
>>>>
>>>> -      CopyMem ((VOID *)LogicalVolDesc, Buffer,
>>>> -               sizeof (UDF_LOGICAL_VOLUME_DESCRIPTOR));
>>>> -      Volume->LogicalVolDescs[Volume->LogicalVolDescsNo++] =
>>>> LogicalVolDesc;
>>>> -    } else if (IS_PD (Buffer)) {
>>>> -      //
>>>> -      // Found a Partition Descriptor.
>>>> -      //
>>>> -      PartitionDesc =
>>>> -        (UDF_PARTITION_DESCRIPTOR *)
>>>> -        AllocateZeroPool (sizeof (UDF_PARTITION_DESCRIPTOR));
>>>> -      if (PartitionDesc == NULL) {
>>>> -        Status = EFI_OUT_OF_RESOURCES;
>>>> -        goto Error_Alloc_Pd;
>>>> -      }
>>>> +    case UdfTerminatingDescriptor:
>>>> +      StopSequence = TRUE;
>>>> +      break;
>>>>
>>>> -      CopyMem ((VOID *)PartitionDesc, Buffer,
>>>> -               sizeof (UDF_PARTITION_DESCRIPTOR));
>>>> -      Volume->PartitionDescs[Volume->PartitionDescsNo++] =
>>>PartitionDesc;
>>>> +    default:
>>>> +      ;
>>>>      }
>>>> -
>>>> -    StartingLsn++;
>>>>    }
>>>>
>>>>    //
>>>> -  // When an UDF volume (revision 2.00 or higher) contains a File
>>>Entry rather
>>>> -  // than an Extended File Entry (which is not recommended as per
>>>spec), we
>>>> need
>>>> -  // to make sure the size of a FE will be _at least_ 2048
>>>> -  // (UDF_LOGICAL_SECTOR_SIZE) bytes long to keep backward
>>>compatibility.
>>>> +  // Determine FE (File Entry) size
>>>>    //
>>>> -  LogicalBlockSize = LV_BLOCK_SIZE (Volume, UDF_DEFAULT_LV_NUM);
>>>> +  LogicalBlockSize = Volume->LogicalVolDesc.LogicalBlockSize;
>>>>    if (LogicalBlockSize >= UDF_LOGICAL_SECTOR_SIZE) {
>>>> -    Volume->FileEntrySize = LogicalBlockSize;
>>>> +    Volume->FileEntrySize = (UINTN)LogicalBlockSize;
>>>>    } else {
>>>>      Volume->FileEntrySize = UDF_LOGICAL_SECTOR_SIZE;
>>>>    }
>>>>
>>>> -  FreePool (Buffer);
>>>> +  Status = EFI_SUCCESS;
>>>>
>>>> -  return EFI_SUCCESS;
>>>> -
>>>> -Error_Alloc_Pd:
>>>> -Error_Alloc_Lvd:
>>>> -  for (Index = 0; Index < Volume->PartitionDescsNo; Index++) {
>>>> -    FreePool ((VOID *)Volume->PartitionDescs[Index]);
>>>> -  }
>>>> -
>>>> -  for (Index = 0; Index < Volume->LogicalVolDescsNo; Index++) {
>>>> -    FreePool ((VOID *)Volume->LogicalVolDescs[Index]);
>>>> -  }
>>>> -
>>>> -Error_Read_Disk_Blk:
>>>> +Out_Free:
>>>> +  //
>>>> +  // Free block read buffer
>>>> +  //
>>>>    FreePool (Buffer);
>>>>
>>>> -Error_Alloc_Buf:
>>>> -  FreePool ((VOID *)Volume->PartitionDescs);
>>>> -  Volume->PartitionDescs = NULL;
>>>> -
>>>> -Error_Alloc_Pds:
>>>> -  FreePool ((VOID *)Volume->LogicalVolDescs);
>>>> -  Volume->LogicalVolDescs = NULL;
>>>> -
>>>>    return Status;
>>>>  }
>>>>
>>>> @@ -262,48 +216,53 @@ GetPdFromLongAd (
>>>>    )
>>>>  {
>>>>    UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;
>>>> -  UINTN                          Index;
>>>> -  UDF_PARTITION_DESCRIPTOR       *PartitionDesc;
>>>>    UINT16                         PartitionNum;
>>>>
>>>> -  LogicalVolDesc = Volume->LogicalVolDescs[UDF_DEFAULT_LV_NUM];
>>>> +  LogicalVolDesc = &Volume->LogicalVolDesc;
>>>>
>>>> -  switch (LV_UDF_REVISION (LogicalVolDesc)) {
>>>> +  switch (UDF_LVD_REVISION (LogicalVolDesc)) {
>>>>    case 0x0102:
>>>> +  case 0x0150:
>>>> +  case 0x0200:
>>>> +  case 0x0201:
>>>> +  case 0x0250:
>>>> +  case 0x0260:
>>>>      //
>>>> -    // As per UDF 1.02 specification:
>>>> +    // UDF 1.02 specification:
>>>>      //
>>>>      // There shall be exactly one prevailing Logical Volume
>>>Descriptor recorded
>>>>      // per Volume Set. The Partition Maps field shall contain only
>>>Type 1
>>>>      // Partition Maps.
>>>>      //
>>>> -    PartitionNum = *(UINT16
>>>*)((UINTN)&LogicalVolDesc->PartitionMaps[4]);
>>>> -    break;
>>>> -  case 0x0150:
>>>> +    // UDF 1.50 through 2.60 specs say:
>>>>      //
>>>> -    // Ensure Type 1 Partition map. Other types aren't supported in
>>>this
>>>> -    // implementation.
>>>> +    // For the purpose of interchange partition maps shall be
>>>limited to
>>>> +    // Partition Map type 1, except type 2 maps as described in the
>>>document.
>>>> +    //
>>>> +    // NOTE: Only one Type 1 (Physical) Partition is supported. It
>>>has been
>>>> +    // checked already in Partition driver for existence of a
>>single
>>>Type 1
>>>> +    // Partition map, so we don't have to double check here.
>>>> +    //
>>>> +    // Partition reference number can also be retrieved from
>>>> +    // LongAd->ExtentLocation.PartitionReferenceNumber, however the
>>>spec
>>>> says
>>>> +    // it may be 0, so let's not rely on it.
>>>>      //
>>>> -    if (LogicalVolDesc->PartitionMaps[0] != 1 ||
>>>> -        LogicalVolDesc->PartitionMaps[1] != 6) {
>>>> -      return NULL;
>>>> -    }
>>>>      PartitionNum = *(UINT16
>>>*)((UINTN)&LogicalVolDesc->PartitionMaps[4]);
>>>>      break;
>>>> -  case 0x0260:
>>>> +
>>>> +  default:
>>>>      //
>>>> -    // Fall through.
>>>> +    // Unsupported UDF revision
>>>>      //
>>>> -  default:
>>>> -    PartitionNum = LongAd->ExtentLocation.PartitionReferenceNumber;
>>>> -    break;
>>>> +    return NULL;
>>>>    }
>>>>
>>>> -
>
> --
> Sent from my Android device with K-9 Mail. Please excuse my brevity.
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel



-- 
Paulo Alcantara, HP
Speaking for myself only.
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Re: [edk2] [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix creation of UDF logical partition
Posted by Zeng, Star 7 years, 3 months ago
Ok, I will go to help push the patch series if Ray has no any comments.

Thanks,
Star
-----Original Message-----
From: Paulo Alcantara [mailto:pcacjr@gmail.com] 
Sent: Thursday, September 21, 2017 10:17 PM
To: Zeng, Star <star.zeng@intel.com>; Wu, Hao A <hao.a.wu@intel.com>; edk2-devel@lists.01.org
Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Laszlo Ersek <lersek@redhat.com>; Dong, Eric <eric.dong@intel.com>
Subject: Re: [edk2] [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix creation of UDF logical partition

On Thu, Sep 21, 2017 at 10:52 AM, Paulo Alcantara <pcacjr@zytor.com> wrote:
>
>
> On September 21, 2017 10:47:07 AM GMT-03:00, "Zeng, Star" <star.zeng@intel.com> wrote:
>>Does it have functional impact?
>
> Nope. When Partition driver walks the partition detect routine table, it executes each routine and then checks for EFI_NO_MEDIA and EFI_MEDIA_CHANGED only. So, the child handle is installed and the EFI_NOT_FOUND is a no-op in that case.

BTW, I performed a quick test with UdfDxe enabled and disabled in OVMF and the removal did not seem to break or change any behavior.

Thanks!
Paulo

>
> Thanks!
> Paulo
>
>>
>>Thanks,
>>Star
>>-----Original Message-----
>>From: Paulo Alcantara [mailto:pcacjr@zytor.com]
>>Sent: Thursday, September 21, 2017 9:29 PM
>>To: Wu, Hao A <hao.a.wu@intel.com>; edk2-devel@lists.01.org
>>Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Laszlo Ersek <lersek@redhat.com>; 
>>Dong, Eric <eric.dong@intel.com>; Zeng, Star <star.zeng@intel.com>
>>Subject: RE: [edk2] [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix 
>>creation of UDF logical partition
>>
>>
>>
>>On September 21, 2017 9:44:10 AM GMT-03:00, "Wu, Hao A"
>><hao.a.wu@intel.com> wrote:
>>>One small comment, within function PartitionInstallUdfChildHandles():
>>>
>>>  ...
>>>  //
>>>  // Install partition child handle for UDF file system
>>>  //
>>>  Status = PartitionInstallChildHandle (
>>>    ...
>>>    );
>>>if (!EFI_ERROR (Status)) {  <----- Is this a typo? "if (EFI_ERROR
>>>(Status)) {"
>>>    Status = EFI_NOT_FOUND;
>>>  }
>>
>>Yes, it is. Good catch! Could you please fix that for me by removing 
>>the if condition? Otherwise I can send a v4 later with that.
>>
>>Thanks!
>>Paulo
>>
>>>
>>>
>>>Best Regards,
>>>Hao Wu
>>>
>>>
>>>> -----Original Message-----
>>>> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf
>>>Of Paulo
>>>> Alcantara
>>>> Sent: Thursday, September 21, 2017 2:16 AM
>>>> To: edk2-devel@lists.01.org
>>>> Cc: Ni, Ruiyu; Laszlo Ersek; Dong, Eric; Zeng, Star
>>>> Subject: [edk2] [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix
>>>creation of
>>>> UDF logical partition
>>>>
>>>> Do not reserve entire block device size for an UDF file system - 
>>>> instead, reserve the appropriate space (UDF logical volume space)
>>for
>>>> it.
>>>>
>>>> Additionally, only create a logical partition for UDF logical
>>volumes
>>>> that are currently supported by EDK2 UDF file system implementation.
>>>For
>>>> instance, an UDF volume with a single LVD and a single Physical
>>(Type
>>>1)
>>>> Partition will be supported.
>>>>
>>>> Cc: Eric Dong <eric.dong@intel.com>
>>>> Cc: Ruiyu Ni <ruiyu.ni@intel.com>
>>>> Cc: Star Zeng <star.zeng@intel.com>
>>>> Cc: Laszlo Ersek <lersek@redhat.com>
>>>> Reported-by: Ruiyu Ni <ruiyu.ni@intel.com>
>>>> Contributed-under: TianoCore Contribution Agreement 1.1
>>>> Signed-off-by: Paulo Alcantara <pcacjr@zytor.com>
>>>> ---
>>>>  MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c            | 363
>>>++++++++++--
>>>>  MdeModulePkg/Universal/Disk/UdfDxe/File.c                 |  16 +-
>>>>  MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c | 627
>>>> ++++++++------------
>>>>  MdeModulePkg/Universal/Disk/UdfDxe/Udf.c                  |   7 -
>>>>  MdeModulePkg/Universal/Disk/UdfDxe/Udf.h                  | 158
>>>++---
>>>>  5 files changed, 606 insertions(+), 565 deletions(-)
>>>>
>>>> diff --git a/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
>>>> b/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
>>>> index 609f56cef6..572ba7a81a 100644
>>>> --- a/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
>>>> +++ b/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
>>>> @@ -64,11 +64,12 @@ FindAnchorVolumeDescriptorPointer (
>>>>    OUT  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint
>>>>    )
>>>>  {
>>>> -  EFI_STATUS  Status;
>>>> -  UINT32      BlockSize;
>>>> -  EFI_LBA     EndLBA;
>>>> -  EFI_LBA     DescriptorLBAs[4];
>>>> -  UINTN       Index;
>>>> +  EFI_STATUS          Status;
>>>> +  UINT32              BlockSize;
>>>> +  EFI_LBA             EndLBA;
>>>> +  EFI_LBA             DescriptorLBAs[4];
>>>> +  UINTN               Index;
>>>> +  UDF_DESCRIPTOR_TAG  *DescriptorTag;
>>>>
>>>>    BlockSize = BlockIo->Media->BlockSize;
>>>>    EndLBA = BlockIo->Media->LastBlock; @@ -88,10 +89,13 @@ 
>>>> FindAnchorVolumeDescriptorPointer (
>>>>      if (EFI_ERROR (Status)) {
>>>>        return Status;
>>>>      }
>>>> +
>>>> +    DescriptorTag = &AnchorPoint->DescriptorTag;
>>>> +
>>>>      //
>>>>      // Check if read LBA has a valid AVDP descriptor.
>>>>      //
>>>> -    if (IS_AVDP (AnchorPoint)) {
>>>> +    if (DescriptorTag->TagIdentifier ==
>>>UdfAnchorVolumeDescriptorPointer) {
>>>>        return EFI_SUCCESS;
>>>>      }
>>>>    }
>>>> @@ -102,23 +106,18 @@ FindAnchorVolumeDescriptorPointer (  }
>>>>
>>>>  /**
>>>> -  Check if block device supports a valid UDF file system as
>>>specified by OSTA
>>>> -  Universal Disk Format Specification 2.60.
>>>> +  Find UDF volume identifiers in a Volume Recognition Sequence.
>>>>
>>>> -  @param[in]   BlockIo  BlockIo interface.
>>>> -  @param[in]   DiskIo   DiskIo interface.
>>>> +  @param[in]  BlockIo             BlockIo interface.
>>>> +  @param[in]  DiskIo              DiskIo interface.
>>>>
>>>> -  @retval EFI_SUCCESS          UDF file system found.
>>>> -  @retval EFI_UNSUPPORTED      UDF file system not found.
>>>> -  @retval EFI_NO_MEDIA         The device has no media.
>>>> -  @retval EFI_DEVICE_ERROR     The device reported an error.
>>>> -  @retval EFI_VOLUME_CORRUPTED The file system structures are
>>>corrupted.
>>>> -  @retval EFI_OUT_OF_RESOURCES The scan was not successful due to
>>>lack of
>>>> -                               resources.
>>>> +  @retval EFI_SUCCESS             UDF volume identifiers were
>>found.
>>>> +  @retval EFI_NOT_FOUND           UDF volume identifiers were not
>>>found.
>>>> +  @retval other                   Failed to perform disk I/O.
>>>>
>>>>  **/
>>>>  EFI_STATUS
>>>> -SupportUdfFileSystem (
>>>> +FindUdfVolumeIdentifiers (
>>>>    IN EFI_BLOCK_IO_PROTOCOL  *BlockIo,
>>>>    IN EFI_DISK_IO_PROTOCOL   *DiskIo
>>>>    )
>>>> @@ -128,7 +127,6 @@ SupportUdfFileSystem (
>>>>    UINT64                                EndDiskOffset;
>>>>    CDROM_VOLUME_DESCRIPTOR               VolDescriptor;
>>>>    CDROM_VOLUME_DESCRIPTOR               TerminatingVolDescriptor;
>>>> -  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  AnchorPoint;
>>>>
>>>>    ZeroMem ((VOID *)&TerminatingVolDescriptor, sizeof 
>>>> (CDROM_VOLUME_DESCRIPTOR));
>>>>
>>>> @@ -167,7 +165,7 @@ SupportUdfFileSystem (
>>>>          (CompareMem ((VOID *)&VolDescriptor,
>>>>                       (VOID *)&TerminatingVolDescriptor,
>>>>                       sizeof (CDROM_VOLUME_DESCRIPTOR)) == 0)) {
>>>> -      return EFI_UNSUPPORTED;
>>>> +      return EFI_NOT_FOUND;
>>>>      }
>>>>    }
>>>>
>>>> @@ -176,7 +174,7 @@ SupportUdfFileSystem (
>>>>    //
>>>>    Offset += UDF_LOGICAL_SECTOR_SIZE;
>>>>    if (Offset >= EndDiskOffset) {
>>>> -    return EFI_UNSUPPORTED;
>>>> +    return EFI_NOT_FOUND;
>>>>    }
>>>>
>>>>    Status = DiskIo->ReadDisk (
>>>> @@ -196,7 +194,7 @@ SupportUdfFileSystem (
>>>>        (CompareMem ((VOID *)VolDescriptor.Unknown.Id,
>>>>                     (VOID *)UDF_NSR3_IDENTIFIER,
>>>>                     sizeof (VolDescriptor.Unknown.Id)) != 0)) {
>>>> -    return EFI_UNSUPPORTED;
>>>> +    return EFI_NOT_FOUND;
>>>>    }
>>>>
>>>>    //
>>>> @@ -204,7 +202,7 @@ SupportUdfFileSystem (
>>>>    //
>>>>    Offset += UDF_LOGICAL_SECTOR_SIZE;
>>>>    if (Offset >= EndDiskOffset) {
>>>> -    return EFI_UNSUPPORTED;
>>>> +    return EFI_NOT_FOUND;
>>>>    }
>>>>
>>>>    Status = DiskIo->ReadDisk (
>>>> @@ -221,15 +219,291 @@ SupportUdfFileSystem (
>>>>    if (CompareMem ((VOID *)VolDescriptor.Unknown.Id,
>>>>                    (VOID *)UDF_TEA_IDENTIFIER,
>>>>                    sizeof (VolDescriptor.Unknown.Id)) != 0) {
>>>> -    return EFI_UNSUPPORTED;
>>>> +    return EFI_NOT_FOUND;
>>>> +  }
>>>> +
>>>> +  return EFI_SUCCESS;
>>>> +}
>>>> +
>>>> +/**
>>>> +  Check if Logical Volume Descriptor is supported by current EDK2
>>>UDF file
>>>> +  system implementation.
>>>> +
>>>> +  @param[in]  LogicalVolDesc  Logical Volume Descriptor pointer.
>>>> +
>>>> +  @retval TRUE                Logical Volume Descriptor is
>>>supported.
>>>> +  @retval FALSE               Logical Volume Descriptor is not
>>>supported.
>>>> +
>>>> +**/
>>>> +BOOLEAN
>>>> +IsLogicalVolumeDescriptorSupported (
>>>> +  UDF_LOGICAL_VOLUME_DESCRIPTOR *LogicalVolDesc
>>>> +  )
>>>> +{
>>>> +  //
>>>> +  // Check for a valid UDF revision range
>>>> +  //
>>>> +  switch (UDF_LVD_REVISION (LogicalVolDesc)) {
>>>> +  case 0x0102:
>>>> +  case 0x0150:
>>>> +  case 0x0200:
>>>> +  case 0x0201:
>>>> +  case 0x0250:
>>>> +  case 0x0260:
>>>> +    break;
>>>> +  default:
>>>> +    return FALSE;
>>>> +  }
>>>> +
>>>> +  //
>>>> +  // Check for a single Partition Map  //  if 
>>>> + (LogicalVolDesc->NumberOfPartitionMaps > 1) {
>>>> +    return FALSE;
>>>> +  }
>>>> +  //
>>>> +  // UDF 1.02 revision supports only Type 1 (Physical) partitions,
>>>but
>>>> +  // let's check it any way.
>>>> +  //
>>>> +  // PartitionMap[0] -> type
>>>> +  // PartitionMap[1] -> length (in bytes)  //  if 
>>>> + (LogicalVolDesc->PartitionMaps[0] != 1 ||
>>>> +      LogicalVolDesc->PartitionMaps[1] != 6) {
>>>> +    return FALSE;
>>>> +  }
>>>> +
>>>> +  return TRUE;
>>>> +}
>>>> +
>>>> +/**
>>>> +  Find UDF logical volume location and whether it is supported by
>>>current EDK2
>>>> +  UDF file system implementation.
>>>> +
>>>> +  @param[in]  BlockIo             BlockIo interface.
>>>> +  @param[in]  DiskIo              DiskIo interface.
>>>> +  @param[in]  AnchorPoint         Anchor volume descriptor pointer.
>>>> +  @param[out] MainVdsStartBlock   Main VDS starting block number.
>>>> +  @param[out] MainVdsEndBlock     Main VDS ending block number.
>>>> +
>>>> +  @retval EFI_SUCCESS             UDF logical volume was found.
>>>> +  @retval EFI_VOLUME_CORRUPTED    UDF file system structures are
>>>> corrupted.
>>>> +  @retval EFI_UNSUPPORTED         UDF logical volume is not
>>>supported.
>>>> +  @retval other                   Failed to perform disk I/O.
>>>> +
>>>> +**/
>>>> +EFI_STATUS
>>>> +FindLogicalVolumeLocation (
>>>> +  IN   EFI_BLOCK_IO_PROTOCOL                 *BlockIo,
>>>> +  IN   EFI_DISK_IO_PROTOCOL                  *DiskIo,
>>>> +  IN   UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint,
>>>> +  OUT  UINT64                                *MainVdsStartBlock,
>>>> +  OUT  UINT64                                *MainVdsEndBlock
>>>> +  )
>>>> +{
>>>> +  EFI_STATUS                     Status;
>>>> +  UINT32                         BlockSize;
>>>> +  EFI_LBA                        LastBlock;
>>>> +  UDF_EXTENT_AD                  *ExtentAd;
>>>> +  UINT64                         SeqBlocksNum;
>>>> +  UINT64                         SeqStartBlock;
>>>> +  UINT64                         GuardMainVdsStartBlock;
>>>> +  VOID                           *Buffer;
>>>> +  UINT64                         SeqEndBlock;
>>>> +  BOOLEAN                        StopSequence;
>>>> +  UINTN                          LvdsCount;
>>>> +  UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;
>>>> +  UDF_DESCRIPTOR_TAG             *DescriptorTag;
>>>> +
>>>> +  BlockSize = BlockIo->Media->BlockSize;  LastBlock =
>>>> + BlockIo->Media->LastBlock;  ExtentAd =
>>>> + &AnchorPoint->MainVolumeDescriptorSequenceExtent;
>>>> +
>>>> +  //
>>>> +  // UDF 2.60, 2.2.3.1 struct MainVolumeDescriptorSequenceExtent
>>>> +  //
>>>> +  // The Main Volume Descriptor Sequence Extent shall have a
>>minimum
>>>length
>>>> of
>>>> +  // 16 logical sectors.
>>>> +  //
>>>> +  // Also make sure it does not exceed maximum number of blocks in
>>>the disk.
>>>> +  //
>>>> +  SeqBlocksNum = DivU64x32 ((UINT64)ExtentAd->ExtentLength,
>>>BlockSize);
>>>> +  if (SeqBlocksNum < 16 || (EFI_LBA)SeqBlocksNum > LastBlock + 1) {
>>>> +    return EFI_VOLUME_CORRUPTED;
>>>> +  }
>>>> +
>>>> +  //
>>>> +  // Check for valid Volume Descriptor Sequence starting block
>>>number
>>>> +  //
>>>> +  SeqStartBlock = (UINT64)ExtentAd->ExtentLocation;  if 
>>>> + (SeqStartBlock > LastBlock ||
>>>> +      SeqStartBlock + SeqBlocksNum - 1 > LastBlock) {
>>>> +    return EFI_VOLUME_CORRUPTED;
>>>>    }
>>>>
>>>> +  GuardMainVdsStartBlock = SeqStartBlock;
>>>> +
>>>> +  //
>>>> +  // Allocate buffer for reading disk blocks  //  Buffer = 
>>>> + AllocateZeroPool ((UINTN)BlockSize);  if (Buffer == NULL) {
>>>> +    return EFI_OUT_OF_RESOURCES;
>>>> +  }
>>>> +
>>>> +  SeqEndBlock = SeqStartBlock + SeqBlocksNum;  StopSequence =
>>FALSE;
>>>> + LvdsCount = 0;  Status = EFI_VOLUME_CORRUPTED;  //  // Start Main 
>>>> + Volume Descriptor Sequence  //  for (; SeqStartBlock < 
>>>> + SeqEndBlock
>>
>>>> + && !StopSequence;
>>>SeqStartBlock++) {
>>>> +    //
>>>> +    // Read disk block
>>>> +    //
>>>> +    Status = BlockIo->ReadBlocks (
>>>> +      BlockIo,
>>>> +      BlockIo->Media->MediaId,
>>>> +      SeqStartBlock,
>>>> +      BlockSize,
>>>> +      Buffer
>>>> +      );
>>>> +    if (EFI_ERROR (Status)) {
>>>> +      goto Out_Free;
>>>> +    }
>>>> +
>>>> +    DescriptorTag = Buffer;
>>>> +
>>>> +    //
>>>> +    // ECMA 167, 8.4.1 Contents of a Volume Descriptor Sequence
>>>> +    //
>>>> +    // - A Volume Descriptor Sequence shall contain one or more
>>>Primary
>>>> Volume
>>>> +    //   Descriptors.
>>>> +    // - A Volume Descriptor Sequence shall contain zero or more
>>>> Implementation
>>>> +    //   Use Volume Descriptors.
>>>> +    // - A Volume Descriptor Sequence shall contain zero or more
>>>Partition
>>>> +    //   Descriptors.
>>>> +    // - A Volume Descriptor Sequence shall contain zero or more
>>>Logical
>>>> Volume
>>>> +    //   Descriptors.
>>>> +    // - A Volume Descriptor Sequence shall contain zero or more
>>>Unallocated
>>>> +    //   Space Descriptors.
>>>> +    //
>>>> +    switch (UDF_TAG_ID (DescriptorTag)) {
>>>> +    case UdfPrimaryVolumeDescriptor:
>>>> +    case UdfImplemenationUseVolumeDescriptor:
>>>> +    case UdfPartitionDescriptor:
>>>> +    case UdfUnallocatedSpaceDescriptor:
>>>> +      break;
>>>> +
>>>> +    case UdfLogicalVolumeDescriptor:
>>>> +      LogicalVolDesc = Buffer;
>>>> +
>>>> +      //
>>>> +      // Check for existence of a single LVD and whether it is
>>>supported by
>>>> +      // current EDK2 UDF file system implementation.
>>>> +      //
>>>> +      if (++LvdsCount > 1 ||
>>>> +          !IsLogicalVolumeDescriptorSupported (LogicalVolDesc)) {
>>>> +        Status = EFI_UNSUPPORTED;
>>>> +        StopSequence = TRUE;
>>>> +      }
>>>> +
>>>> +      break;
>>>> +
>>>> +    case UdfTerminatingDescriptor:
>>>> +      //
>>>> +      // Stop the sequence when we find a Terminating Descriptor
>>>> +      // (aka Unallocated Sector), se we don't have to walk all 
>>>> + the
>>>unallocated
>>>> +      // area unnecessarily.
>>>> +      //
>>>> +      StopSequence = TRUE;
>>>> +      break;
>>>> +
>>>> +    default:
>>>> +      //
>>>> +      // An invalid Volume Descriptor has been found in the
>>sequece.
>>>Volume is
>>>> +      // corrupted.
>>>> +      //
>>>> +      Status = EFI_VOLUME_CORRUPTED;
>>>> +      goto Out_Free;
>>>> +    }
>>>> +  }
>>>> +
>>>> +  //
>>>> +  // Check if LVD was found
>>>> +  //
>>>> +  if (!EFI_ERROR (Status) && LvdsCount == 1) {
>>>> +    *MainVdsStartBlock = GuardMainVdsStartBlock;
>>>> +    //
>>>> +    // We do not need to read either LVD or PD descriptors to know
>>>the last
>>>> +    // valid block in the found UDF file system. It's already
>>>LastBlock.
>>>> +    //
>>>> +    *MainVdsEndBlock = LastBlock;
>>>> +
>>>> +    Status = EFI_SUCCESS;
>>>> +  }
>>>> +
>>>> +Out_Free:
>>>> +  //
>>>> +  // Free block read buffer
>>>> +  //
>>>> +  FreePool (Buffer);
>>>> +
>>>> +  return Status;
>>>> +}
>>>> +
>>>> +/**
>>>> +  Find a supported UDF file system in block device.
>>>> +
>>>> +  @param[in]  BlockIo             BlockIo interface.
>>>> +  @param[in]  DiskIo              DiskIo interface.
>>>> +  @param[out] StartingLBA         UDF file system starting LBA.
>>>> +  @param[out] EndingLBA           UDF file system starting LBA.
>>>> +
>>>> +  @retval EFI_SUCCESS             UDF file system was found.
>>>> +  @retval other                   UDF file system was not found.
>>>> +
>>>> +**/
>>>> +EFI_STATUS
>>>> +FindUdfFileSystem (
>>>> +  IN EFI_BLOCK_IO_PROTOCOL  *BlockIo,
>>>> +  IN EFI_DISK_IO_PROTOCOL   *DiskIo,
>>>> +  OUT EFI_LBA               *StartingLBA,
>>>> +  OUT EFI_LBA               *EndingLBA
>>>> +  )
>>>> +{
>>>> +  EFI_STATUS Status;
>>>> +  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  AnchorPoint;
>>>> +
>>>> +  //
>>>> +  // Find UDF volume identifiers
>>>> +  //
>>>> +  Status = FindUdfVolumeIdentifiers (BlockIo, DiskIo);  if 
>>>> + (EFI_ERROR (Status)) {
>>>> +    return Status;
>>>> +  }
>>>> +
>>>> +  //
>>>> +  // Find Anchor Volume Descriptor Pointer  //
>>>>    Status = FindAnchorVolumeDescriptorPointer (BlockIo, DiskIo,
>>>&AnchorPoint);
>>>>    if (EFI_ERROR (Status)) {
>>>> -    return EFI_UNSUPPORTED;
>>>> +    return Status;
>>>>    }
>>>>
>>>> -  return EFI_SUCCESS;
>>>> +  //
>>>> +  // Find Logical Volume location
>>>> +  //
>>>> +  Status = FindLogicalVolumeLocation (
>>>> +    BlockIo,
>>>> +    DiskIo,
>>>> +    &AnchorPoint,
>>>> +    (UINT64 *)StartingLBA,
>>>> +    (UINT64 *)EndingLBA
>>>> +    );
>>>> +
>>>> +  return Status;
>>>>  }
>>>>
>>>>  /**
>>>> @@ -263,9 +537,9 @@ PartitionInstallUdfChildHandles (
>>>>    UINT32                       RemainderByMediaBlockSize;
>>>>    EFI_STATUS                   Status;
>>>>    EFI_BLOCK_IO_MEDIA           *Media;
>>>> -  EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode;
>>>> -  EFI_GUID                     *VendorDefinedGuid;
>>>>    EFI_PARTITION_INFO_PROTOCOL  PartitionInfo;
>>>> +  EFI_LBA                      StartingLBA;
>>>> +  EFI_LBA                      EndingLBA;
>>>>
>>>>    Media = BlockIo->Media;
>>>>
>>>> @@ -281,35 +555,10 @@ PartitionInstallUdfChildHandles (
>>>>      return EFI_NOT_FOUND;
>>>>    }
>>>>
>>>> -  DevicePathNode = DevicePath;
>>>> -  while (!IsDevicePathEnd (DevicePathNode)) {
>>>> -    //
>>>> -    // Do not allow checking for UDF file systems in CDROM "El
>>>Torito"
>>>> -    // partitions, and skip duplicate installation of UDF file
>>>system child
>>>> -    // nodes.
>>>> -    //
>>>> -    if (DevicePathType (DevicePathNode) == MEDIA_DEVICE_PATH) {
>>>> -      if (DevicePathSubType (DevicePathNode) == MEDIA_CDROM_DP) {
>>>> -        return EFI_NOT_FOUND;
>>>> -      }
>>>> -      if (DevicePathSubType (DevicePathNode) == MEDIA_VENDOR_DP) {
>>>> -        VendorDefinedGuid = (EFI_GUID *)((UINTN)DevicePathNode +
>>>> -                                         OFFSET_OF
>>>(VENDOR_DEVICE_PATH, Guid));
>>>> -        if (CompareGuid (VendorDefinedGuid, &gUdfDevPathGuid)) {
>>>> -          return EFI_NOT_FOUND;
>>>> -        }
>>>> -      }
>>>> -    }
>>>> -    //
>>>> -    // Try next device path node
>>>> -    //
>>>> -    DevicePathNode = NextDevicePathNode (DevicePathNode);
>>>> -  }
>>>> -
>>>>    //
>>>> -  // Check if block device supports an UDF file system
>>>> +  // Search for an UDF file system on block device
>>>>    //
>>>> -  Status = SupportUdfFileSystem (BlockIo, DiskIo);
>>>> +  Status = FindUdfFileSystem (BlockIo, DiskIo, &StartingLBA,
>>>&EndingLBA);
>>>>    if (EFI_ERROR (Status)) {
>>>>      return EFI_NOT_FOUND;
>>>>    }
>>>> @@ -334,8 +583,8 @@ PartitionInstallUdfChildHandles (
>>>>      DevicePath,
>>>>      (EFI_DEVICE_PATH_PROTOCOL *)&gUdfDevicePath,
>>>>      &PartitionInfo,
>>>> -    0,
>>>> -    Media->LastBlock,
>>>> +    StartingLBA,
>>>> +    EndingLBA,
>>>>      Media->BlockSize
>>>>      );
>>>>    if (!EFI_ERROR (Status)) {
>>>> diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/File.c
>>>> b/MdeModulePkg/Universal/Disk/UdfDxe/File.c
>>>> index 625f2c5637..6f07bf2066 100644
>>>> --- a/MdeModulePkg/Universal/Disk/UdfDxe/File.c
>>>> +++ b/MdeModulePkg/Universal/Disk/UdfDxe/File.c
>>>> @@ -131,7 +131,6 @@ Error_Alloc_Priv_File_Data:
>>>>    CleanupFileInformation (&PrivFsData->Root);
>>>>
>>>>  Error_Find_Root_Dir:
>>>> -  CleanupVolumeInformation (&PrivFsData->Volume);
>>>>
>>>>  Error_Read_Udf_Volume:
>>>>  Error_Invalid_Params:
>>>> @@ -429,7 +428,7 @@ UdfRead (
>>>>      }
>>>>      ASSERT (NewFileEntryData != NULL);
>>>>
>>>> -    if (IS_FE_SYMLINK (NewFileEntryData)) {
>>>> +    if (FE_ICB_FILE_TYPE (NewFileEntryData) == 
>>>> + UdfFileEntrySymlink)
>>>{
>>>>        Status = ResolveSymlink (
>>>>          BlockIo,
>>>>          DiskIo,
>>>> @@ -529,7 +528,6 @@ UdfClose (
>>>>    EFI_TPL                     OldTpl;
>>>>    EFI_STATUS                  Status;
>>>>    PRIVATE_UDF_FILE_DATA       *PrivFileData;
>>>> -  PRIVATE_UDF_SIMPLE_FS_DATA  *PrivFsData;
>>>>
>>>>    OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
>>>>
>>>> @@ -542,8 +540,6 @@ UdfClose (
>>>>
>>>>    PrivFileData = PRIVATE_UDF_FILE_DATA_FROM_THIS (This);
>>>>
>>>> -  PrivFsData = PRIVATE_UDF_SIMPLE_FS_DATA_FROM_THIS (PrivFileData-
>>>> >SimpleFs);
>>>> -
>>>>    if (!PrivFileData->IsRootDirectory) {
>>>>      CleanupFileInformation (&PrivFileData->File);
>>>>
>>>> @@ -552,10 +548,6 @@ UdfClose (
>>>>      }
>>>>    }
>>>>
>>>> -  if (--PrivFsData->OpenFiles == 0) {
>>>> -    CleanupVolumeInformation (&PrivFsData->Volume);
>>>> -  }
>>>> -
>>>>    FreePool ((VOID *)PrivFileData);
>>>>
>>>>  Exit:
>>>> @@ -652,7 +644,7 @@ UdfGetPosition (
>>>>    // As per UEFI spec, if the file handle is a directory, then the
>>>current file
>>>>    // position has no meaning and the operation is not supported.
>>>>    //
>>>> -  if (IS_FID_DIRECTORY_FILE
>>>(&PrivFileData->File.FileIdentifierDesc)) {
>>>> +  if (IS_FID_DIRECTORY_FILE
>>(PrivFileData->File.FileIdentifierDesc))
>>>{
>>>>      return  EFI_UNSUPPORTED;
>>>>    }
>>>>
>>>> @@ -788,7 +780,7 @@ UdfGetInfo (
>>>>    } else if (CompareGuid (InformationType,
>>&gEfiFileSystemInfoGuid))
>>>{
>>>>      String = VolumeLabel;
>>>>
>>>> -    FileSetDesc = PrivFsData->Volume.FileSetDescs[0];
>>>> +    FileSetDesc = &PrivFsData->Volume.FileSetDesc;
>>>>
>>>>      OstaCompressed = &FileSetDesc->LogicalVolumeIdentifier[0];
>>>>
>>>> @@ -847,7 +839,7 @@ UdfGetInfo (
>>>>      FileSystemInfo->Size        = FileSystemInfoLength;
>>>>      FileSystemInfo->ReadOnly    = TRUE;
>>>>      FileSystemInfo->BlockSize   =
>>>> -      LV_BLOCK_SIZE (&PrivFsData->Volume, UDF_DEFAULT_LV_NUM);
>>>> +      PrivFsData->Volume.LogicalVolDesc.LogicalBlockSize;
>>>>      FileSystemInfo->VolumeSize  = VolumeSize;
>>>>      FileSystemInfo->FreeSpace   = FreeSpaceSize;
>>>>
>>>> diff --git
>>>a/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
>>>> b/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
>>>> index 5df267761f..62d817989f 100644
>>>> --- a/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
>>>> +++ b/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
>>>> @@ -38,11 +38,12 @@ FindAnchorVolumeDescriptorPointer (
>>>>    OUT  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint
>>>>    )
>>>>  {
>>>> -  EFI_STATUS  Status;
>>>> -  UINT32      BlockSize;
>>>> -  EFI_LBA     EndLBA;
>>>> -  EFI_LBA     DescriptorLBAs[4];
>>>> -  UINTN       Index;
>>>> +  EFI_STATUS          Status;
>>>> +  UINT32              BlockSize;
>>>> +  EFI_LBA             EndLBA;
>>>> +  EFI_LBA             DescriptorLBAs[4];
>>>> +  UINTN               Index;
>>>> +  UDF_DESCRIPTOR_TAG  *DescriptorTag;
>>>>
>>>>    BlockSize = BlockIo->Media->BlockSize;
>>>>    EndLBA = BlockIo->Media->LastBlock; @@ -62,10 +63,13 @@ 
>>>> FindAnchorVolumeDescriptorPointer (
>>>>      if (EFI_ERROR (Status)) {
>>>>        return Status;
>>>>      }
>>>> +
>>>> +    DescriptorTag = &AnchorPoint->DescriptorTag;
>>>> +
>>>>      //
>>>>      // Check if read LBA has a valid AVDP descriptor.
>>>>      //
>>>> -    if (IS_AVDP (AnchorPoint)) {
>>>> +    if (DescriptorTag->TagIdentifier ==
>>>UdfAnchorVolumeDescriptorPointer) {
>>>>        return EFI_SUCCESS;
>>>>      }
>>>>    }
>>>> @@ -99,148 +103,98 @@ StartMainVolumeDescriptorSequence (
>>>>    OUT  UDF_VOLUME_INFO                       *Volume
>>>>    )
>>>>  {
>>>> -  EFI_STATUS                     Status;
>>>> -  UINT32                         BlockSize;
>>>> -  UDF_EXTENT_AD                  *ExtentAd;
>>>> -  UINT64                         StartingLsn;
>>>> -  UINT64                         EndingLsn;
>>>> -  VOID                           *Buffer;
>>>> -  UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;
>>>> -  UDF_PARTITION_DESCRIPTOR       *PartitionDesc;
>>>> -  UINTN                          Index;
>>>> -  UINT32                         LogicalBlockSize;
>>>> +  EFI_STATUS            Status;
>>>> +  UINT32                BlockSize;
>>>> +  UDF_EXTENT_AD         *ExtentAd;
>>>> +  EFI_LBA               SeqStartBlock;
>>>> +  EFI_LBA               SeqEndBlock;
>>>> +  BOOLEAN               StopSequence;
>>>> +  VOID                  *Buffer;
>>>> +  UDF_DESCRIPTOR_TAG    *DescriptorTag;
>>>> +  UINT32                LogicalBlockSize;
>>>> +
>>>> +  BlockSize = BlockIo->Media->BlockSize;  ExtentAd = 
>>>> + &AnchorPoint->MainVolumeDescriptorSequenceExtent;
>>>>
>>>>    //
>>>> -  // We've already found an ADVP on the volume. It contains the
>>>extent
>>>> -  // (MainVolumeDescriptorSequenceExtent) where the Main Volume 
>>>> Descriptor
>>>> -  // Sequence starts. Therefore, we'll look for Logical Volume
>>>Descriptors and
>>>> -  // Partitions Descriptors and save them in memory, accordingly.
>>>> -  //
>>>> -  // Note also that each descriptor will be aligned on a block 
>>>> size
>>>(BlockSize)
>>>> -  // boundary, so we need to read one block at a time.
>>>> +  // Allocate buffer for reading disk blocks
>>>>    //
>>>> -  BlockSize    = BlockIo->Media->BlockSize;
>>>> -  ExtentAd     = &AnchorPoint->MainVolumeDescriptorSequenceExtent;
>>>> -  StartingLsn  = (UINT64)ExtentAd->ExtentLocation;
>>>> -  EndingLsn    = StartingLsn + DivU64x32 (
>>>> -
>>(UINT64)ExtentAd->ExtentLength,
>>>> -                                     BlockSize
>>>> -                                     );
>>>> -
>>>> -  Volume->LogicalVolDescs =
>>>> -    (UDF_LOGICAL_VOLUME_DESCRIPTOR **)AllocateZeroPool (ExtentAd-
>>>> >ExtentLength);
>>>> -  if (Volume->LogicalVolDescs == NULL) {
>>>> -    return EFI_OUT_OF_RESOURCES;
>>>> -  }
>>>> -
>>>> -  Volume->PartitionDescs =
>>>> -    (UDF_PARTITION_DESCRIPTOR **)AllocateZeroPool (ExtentAd-
>>>> >ExtentLength);
>>>> -  if (Volume->PartitionDescs == NULL) {
>>>> -    Status = EFI_OUT_OF_RESOURCES;
>>>> -    goto Error_Alloc_Pds;
>>>> -  }
>>>> -
>>>> -  Buffer = AllocateZeroPool (BlockSize);
>>>> +  Buffer = AllocateZeroPool ((UINTN)BlockSize);
>>>>    if (Buffer == NULL) {
>>>> -    Status = EFI_OUT_OF_RESOURCES;
>>>> -    goto Error_Alloc_Buf;
>>>> +    return EFI_OUT_OF_RESOURCES;
>>>>    }
>>>>
>>>> -  Volume->LogicalVolDescsNo  = 0;
>>>> -  Volume->PartitionDescsNo   = 0;
>>>> -
>>>> -  while (StartingLsn <= EndingLsn) {
>>>> -    Status = DiskIo->ReadDisk (
>>>> -      DiskIo,
>>>> +  //
>>>> +  // The logical partition created by Partition driver is relative
>>>to the main
>>>> +  // VDS extent location, so we start the Main Volume Descriptor
>>>Sequence at
>>>> +  // LBA 0.
>>>> +  //
>>>> +  // We don't need to check again if we have valid Volume
>>>Descriptors here
>>>> since
>>>> +  // Partition driver already did.
>>>> +  //
>>>> +  SeqStartBlock = 0;
>>>> +  SeqEndBlock = SeqStartBlock + DivU64x32
>>>((UINT64)ExtentAd->ExtentLength,
>>>> +                                           BlockSize);
>>StopSequence
>>>> + = FALSE;  for (; SeqStartBlock < SeqEndBlock && !StopSequence;
>>>SeqStartBlock++) {
>>>> +    //
>>>> +    // Read disk block
>>>> +    //
>>>> +    Status = BlockIo->ReadBlocks (
>>>> +      BlockIo,
>>>>        BlockIo->Media->MediaId,
>>>> -      MultU64x32 (StartingLsn, BlockSize),
>>>> +      SeqStartBlock,
>>>>        BlockSize,
>>>>        Buffer
>>>>        );
>>>>      if (EFI_ERROR (Status)) {
>>>> -      goto Error_Read_Disk_Blk;
>>>> +      goto Out_Free;
>>>>      }
>>>>
>>>> -    if (IS_TD (Buffer)) {
>>>> +    DescriptorTag = Buffer;
>>>> +
>>>> +    switch (UDF_TAG_ID (DescriptorTag)) {
>>>> +    case UdfPartitionDescriptor:
>>>>        //
>>>> -      // Found a Terminating Descriptor. Stop the sequence then.
>>>> +      // Save Partition Descriptor
>>>>        //
>>>> +      CopyMem (&Volume->PartitionDesc, Buffer, sizeof (Volume-
>>>> >PartitionDesc));
>>>>        break;
>>>> -    }
>>>>
>>>> -    if (IS_LVD (Buffer)) {
>>>> +    case UdfLogicalVolumeDescriptor:
>>>>        //
>>>> -      // Found a Logical Volume Descriptor.
>>>> +      // Save Logical Volume Descriptor
>>>>        //
>>>> -      LogicalVolDesc =
>>>> -        (UDF_LOGICAL_VOLUME_DESCRIPTOR *)
>>>> -        AllocateZeroPool (sizeof (UDF_LOGICAL_VOLUME_DESCRIPTOR));
>>>> -      if (LogicalVolDesc == NULL) {
>>>> -        Status = EFI_OUT_OF_RESOURCES;
>>>> -        goto Error_Alloc_Lvd;
>>>> -      }
>>>> +      CopyMem (&Volume->LogicalVolDesc, Buffer, sizeof (Volume-
>>>> >LogicalVolDesc));
>>>> +      break;
>>>>
>>>> -      CopyMem ((VOID *)LogicalVolDesc, Buffer,
>>>> -               sizeof (UDF_LOGICAL_VOLUME_DESCRIPTOR));
>>>> -      Volume->LogicalVolDescs[Volume->LogicalVolDescsNo++] =
>>>> LogicalVolDesc;
>>>> -    } else if (IS_PD (Buffer)) {
>>>> -      //
>>>> -      // Found a Partition Descriptor.
>>>> -      //
>>>> -      PartitionDesc =
>>>> -        (UDF_PARTITION_DESCRIPTOR *)
>>>> -        AllocateZeroPool (sizeof (UDF_PARTITION_DESCRIPTOR));
>>>> -      if (PartitionDesc == NULL) {
>>>> -        Status = EFI_OUT_OF_RESOURCES;
>>>> -        goto Error_Alloc_Pd;
>>>> -      }
>>>> +    case UdfTerminatingDescriptor:
>>>> +      StopSequence = TRUE;
>>>> +      break;
>>>>
>>>> -      CopyMem ((VOID *)PartitionDesc, Buffer,
>>>> -               sizeof (UDF_PARTITION_DESCRIPTOR));
>>>> -      Volume->PartitionDescs[Volume->PartitionDescsNo++] =
>>>PartitionDesc;
>>>> +    default:
>>>> +      ;
>>>>      }
>>>> -
>>>> -    StartingLsn++;
>>>>    }
>>>>
>>>>    //
>>>> -  // When an UDF volume (revision 2.00 or higher) contains a File
>>>Entry rather
>>>> -  // than an Extended File Entry (which is not recommended as per
>>>spec), we
>>>> need
>>>> -  // to make sure the size of a FE will be _at least_ 2048
>>>> -  // (UDF_LOGICAL_SECTOR_SIZE) bytes long to keep backward
>>>compatibility.
>>>> +  // Determine FE (File Entry) size
>>>>    //
>>>> -  LogicalBlockSize = LV_BLOCK_SIZE (Volume, UDF_DEFAULT_LV_NUM);
>>>> +  LogicalBlockSize = Volume->LogicalVolDesc.LogicalBlockSize;
>>>>    if (LogicalBlockSize >= UDF_LOGICAL_SECTOR_SIZE) {
>>>> -    Volume->FileEntrySize = LogicalBlockSize;
>>>> +    Volume->FileEntrySize = (UINTN)LogicalBlockSize;
>>>>    } else {
>>>>      Volume->FileEntrySize = UDF_LOGICAL_SECTOR_SIZE;
>>>>    }
>>>>
>>>> -  FreePool (Buffer);
>>>> +  Status = EFI_SUCCESS;
>>>>
>>>> -  return EFI_SUCCESS;
>>>> -
>>>> -Error_Alloc_Pd:
>>>> -Error_Alloc_Lvd:
>>>> -  for (Index = 0; Index < Volume->PartitionDescsNo; Index++) {
>>>> -    FreePool ((VOID *)Volume->PartitionDescs[Index]);
>>>> -  }
>>>> -
>>>> -  for (Index = 0; Index < Volume->LogicalVolDescsNo; Index++) {
>>>> -    FreePool ((VOID *)Volume->LogicalVolDescs[Index]);
>>>> -  }
>>>> -
>>>> -Error_Read_Disk_Blk:
>>>> +Out_Free:
>>>> +  //
>>>> +  // Free block read buffer
>>>> +  //
>>>>    FreePool (Buffer);
>>>>
>>>> -Error_Alloc_Buf:
>>>> -  FreePool ((VOID *)Volume->PartitionDescs);
>>>> -  Volume->PartitionDescs = NULL;
>>>> -
>>>> -Error_Alloc_Pds:
>>>> -  FreePool ((VOID *)Volume->LogicalVolDescs);
>>>> -  Volume->LogicalVolDescs = NULL;
>>>> -
>>>>    return Status;
>>>>  }
>>>>
>>>> @@ -262,48 +216,53 @@ GetPdFromLongAd (
>>>>    )
>>>>  {
>>>>    UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;
>>>> -  UINTN                          Index;
>>>> -  UDF_PARTITION_DESCRIPTOR       *PartitionDesc;
>>>>    UINT16                         PartitionNum;
>>>>
>>>> -  LogicalVolDesc = Volume->LogicalVolDescs[UDF_DEFAULT_LV_NUM];
>>>> +  LogicalVolDesc = &Volume->LogicalVolDesc;
>>>>
>>>> -  switch (LV_UDF_REVISION (LogicalVolDesc)) {
>>>> +  switch (UDF_LVD_REVISION (LogicalVolDesc)) {
>>>>    case 0x0102:
>>>> +  case 0x0150:
>>>> +  case 0x0200:
>>>> +  case 0x0201:
>>>> +  case 0x0250:
>>>> +  case 0x0260:
>>>>      //
>>>> -    // As per UDF 1.02 specification:
>>>> +    // UDF 1.02 specification:
>>>>      //
>>>>      // There shall be exactly one prevailing Logical Volume
>>>Descriptor recorded
>>>>      // per Volume Set. The Partition Maps field shall contain only
>>>Type 1
>>>>      // Partition Maps.
>>>>      //
>>>> -    PartitionNum = *(UINT16
>>>*)((UINTN)&LogicalVolDesc->PartitionMaps[4]);
>>>> -    break;
>>>> -  case 0x0150:
>>>> +    // UDF 1.50 through 2.60 specs say:
>>>>      //
>>>> -    // Ensure Type 1 Partition map. Other types aren't supported in
>>>this
>>>> -    // implementation.
>>>> +    // For the purpose of interchange partition maps shall be
>>>limited to
>>>> +    // Partition Map type 1, except type 2 maps as described in 
>>>> + the
>>>document.
>>>> +    //
>>>> +    // NOTE: Only one Type 1 (Physical) Partition is supported. It
>>>has been
>>>> +    // checked already in Partition driver for existence of a
>>single
>>>Type 1
>>>> +    // Partition map, so we don't have to double check here.
>>>> +    //
>>>> +    // Partition reference number can also be retrieved from
>>>> +    // LongAd->ExtentLocation.PartitionReferenceNumber, however 
>>>> + the
>>>spec
>>>> says
>>>> +    // it may be 0, so let's not rely on it.
>>>>      //
>>>> -    if (LogicalVolDesc->PartitionMaps[0] != 1 ||
>>>> -        LogicalVolDesc->PartitionMaps[1] != 6) {
>>>> -      return NULL;
>>>> -    }
>>>>      PartitionNum = *(UINT16
>>>*)((UINTN)&LogicalVolDesc->PartitionMaps[4]);
>>>>      break;
>>>> -  case 0x0260:
>>>> +
>>>> +  default:
>>>>      //
>>>> -    // Fall through.
>>>> +    // Unsupported UDF revision
>>>>      //
>>>> -  default:
>>>> -    PartitionNum = LongAd->ExtentLocation.PartitionReferenceNumber;
>>>> -    break;
>>>> +    return NULL;
>>>>    }
>>>>
>>>> -
>
> --
> Sent from my Android device with K-9 Mail. Please excuse my brevity.
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel



--
Paulo Alcantara, HP
Speaking for myself only.
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Re: [edk2] [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix creation of UDF logical partition
Posted by Ni, Ruiyu 7 years, 3 months ago
Paulo,
Are you ok to the macro related comments I provided to patch V3.#1?
If yes, could you please update the patch V3.#2 accordingly?

I noticed that you put some structures that seem to be UDF standard
into the UdfDxe driver local header file.
I am ok with your decision. For public interfaces, none is better than bad.

I also checked a bit of your updated code, but didn't dig into very details.
I am ok to the logic.

Thanks/Ray

> -----Original Message-----
> From: Zeng, Star
> Sent: Friday, September 22, 2017 10:27 AM
> To: Paulo Alcantara <pcacjr@gmail.com>; Wu, Hao A <hao.a.wu@intel.com>;
> edk2-devel@lists.01.org
> Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Laszlo Ersek <lersek@redhat.com>; Dong,
> Eric <eric.dong@intel.com>; Zeng, Star <star.zeng@intel.com>
> Subject: RE: [edk2] [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix creation
> of UDF logical partition
> 
> Ok, I will go to help push the patch series if Ray has no any comments.
> 
> Thanks,
> Star
> -----Original Message-----
> From: Paulo Alcantara [mailto:pcacjr@gmail.com]
> Sent: Thursday, September 21, 2017 10:17 PM
> To: Zeng, Star <star.zeng@intel.com>; Wu, Hao A <hao.a.wu@intel.com>;
> edk2-devel@lists.01.org
> Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Laszlo Ersek <lersek@redhat.com>; Dong,
> Eric <eric.dong@intel.com>
> Subject: Re: [edk2] [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix
> creation of UDF logical partition
> 
> On Thu, Sep 21, 2017 at 10:52 AM, Paulo Alcantara <pcacjr@zytor.com>
> wrote:
> >
> >
> > On September 21, 2017 10:47:07 AM GMT-03:00, "Zeng, Star"
> <star.zeng@intel.com> wrote:
> >>Does it have functional impact?
> >
> > Nope. When Partition driver walks the partition detect routine table, it
> executes each routine and then checks for EFI_NO_MEDIA and
> EFI_MEDIA_CHANGED only. So, the child handle is installed and the
> EFI_NOT_FOUND is a no-op in that case.
> 
> BTW, I performed a quick test with UdfDxe enabled and disabled in OVMF
> and the removal did not seem to break or change any behavior.
> 
> Thanks!
> Paulo
> 
> >
> > Thanks!
> > Paulo
> >
> >>
> >>Thanks,
> >>Star
> >>-----Original Message-----
> >>From: Paulo Alcantara [mailto:pcacjr@zytor.com]
> >>Sent: Thursday, September 21, 2017 9:29 PM
> >>To: Wu, Hao A <hao.a.wu@intel.com>; edk2-devel@lists.01.org
> >>Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Laszlo Ersek <lersek@redhat.com>;
> >>Dong, Eric <eric.dong@intel.com>; Zeng, Star <star.zeng@intel.com>
> >>Subject: RE: [edk2] [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix
> >>creation of UDF logical partition
> >>
> >>
> >>
> >>On September 21, 2017 9:44:10 AM GMT-03:00, "Wu, Hao A"
> >><hao.a.wu@intel.com> wrote:
> >>>One small comment, within function PartitionInstallUdfChildHandles():
> >>>
> >>>  ...
> >>>  //
> >>>  // Install partition child handle for UDF file system
> >>>  //
> >>>  Status = PartitionInstallChildHandle (
> >>>    ...
> >>>    );
> >>>if (!EFI_ERROR (Status)) {  <----- Is this a typo? "if (EFI_ERROR
> >>>(Status)) {"
> >>>    Status = EFI_NOT_FOUND;
> >>>  }
> >>
> >>Yes, it is. Good catch! Could you please fix that for me by removing
> >>the if condition? Otherwise I can send a v4 later with that.
> >>
> >>Thanks!
> >>Paulo
> >>
> >>>
> >>>
> >>>Best Regards,
> >>>Hao Wu
> >>>
> >>>
> >>>> -----Original Message-----
> >>>> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf
> >>>Of Paulo
> >>>> Alcantara
> >>>> Sent: Thursday, September 21, 2017 2:16 AM
> >>>> To: edk2-devel@lists.01.org
> >>>> Cc: Ni, Ruiyu; Laszlo Ersek; Dong, Eric; Zeng, Star
> >>>> Subject: [edk2] [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix
> >>>creation of
> >>>> UDF logical partition
> >>>>
> >>>> Do not reserve entire block device size for an UDF file system -
> >>>> instead, reserve the appropriate space (UDF logical volume space)
> >>for
> >>>> it.
> >>>>
> >>>> Additionally, only create a logical partition for UDF logical
> >>volumes
> >>>> that are currently supported by EDK2 UDF file system implementation.
> >>>For
> >>>> instance, an UDF volume with a single LVD and a single Physical
> >>(Type
> >>>1)
> >>>> Partition will be supported.
> >>>>
> >>>> Cc: Eric Dong <eric.dong@intel.com>
> >>>> Cc: Ruiyu Ni <ruiyu.ni@intel.com>
> >>>> Cc: Star Zeng <star.zeng@intel.com>
> >>>> Cc: Laszlo Ersek <lersek@redhat.com>
> >>>> Reported-by: Ruiyu Ni <ruiyu.ni@intel.com>
> >>>> Contributed-under: TianoCore Contribution Agreement 1.1
> >>>> Signed-off-by: Paulo Alcantara <pcacjr@zytor.com>
> >>>> ---
> >>>>  MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c            | 363
> >>>++++++++++--
> >>>>  MdeModulePkg/Universal/Disk/UdfDxe/File.c                 |  16 +-
> >>>>  MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c | 627
> >>>> ++++++++------------
> >>>>  MdeModulePkg/Universal/Disk/UdfDxe/Udf.c                  |   7 -
> >>>>  MdeModulePkg/Universal/Disk/UdfDxe/Udf.h                  | 158
> >>>++---
> >>>>  5 files changed, 606 insertions(+), 565 deletions(-)
> >>>>
> >>>> diff --git a/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
> >>>> b/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
> >>>> index 609f56cef6..572ba7a81a 100644
> >>>> --- a/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
> >>>> +++ b/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
> >>>> @@ -64,11 +64,12 @@ FindAnchorVolumeDescriptorPointer (
> >>>>    OUT  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint
> >>>>    )
> >>>>  {
> >>>> -  EFI_STATUS  Status;
> >>>> -  UINT32      BlockSize;
> >>>> -  EFI_LBA     EndLBA;
> >>>> -  EFI_LBA     DescriptorLBAs[4];
> >>>> -  UINTN       Index;
> >>>> +  EFI_STATUS          Status;
> >>>> +  UINT32              BlockSize;
> >>>> +  EFI_LBA             EndLBA;
> >>>> +  EFI_LBA             DescriptorLBAs[4];
> >>>> +  UINTN               Index;
> >>>> +  UDF_DESCRIPTOR_TAG  *DescriptorTag;
> >>>>
> >>>>    BlockSize = BlockIo->Media->BlockSize;
> >>>>    EndLBA = BlockIo->Media->LastBlock; @@ -88,10 +89,13 @@
> >>>> FindAnchorVolumeDescriptorPointer (
> >>>>      if (EFI_ERROR (Status)) {
> >>>>        return Status;
> >>>>      }
> >>>> +
> >>>> +    DescriptorTag = &AnchorPoint->DescriptorTag;
> >>>> +
> >>>>      //
> >>>>      // Check if read LBA has a valid AVDP descriptor.
> >>>>      //
> >>>> -    if (IS_AVDP (AnchorPoint)) {
> >>>> +    if (DescriptorTag->TagIdentifier ==
> >>>UdfAnchorVolumeDescriptorPointer) {
> >>>>        return EFI_SUCCESS;
> >>>>      }
> >>>>    }
> >>>> @@ -102,23 +106,18 @@ FindAnchorVolumeDescriptorPointer (  }
> >>>>
> >>>>  /**
> >>>> -  Check if block device supports a valid UDF file system as
> >>>specified by OSTA
> >>>> -  Universal Disk Format Specification 2.60.
> >>>> +  Find UDF volume identifiers in a Volume Recognition Sequence.
> >>>>
> >>>> -  @param[in]   BlockIo  BlockIo interface.
> >>>> -  @param[in]   DiskIo   DiskIo interface.
> >>>> +  @param[in]  BlockIo             BlockIo interface.
> >>>> +  @param[in]  DiskIo              DiskIo interface.
> >>>>
> >>>> -  @retval EFI_SUCCESS          UDF file system found.
> >>>> -  @retval EFI_UNSUPPORTED      UDF file system not found.
> >>>> -  @retval EFI_NO_MEDIA         The device has no media.
> >>>> -  @retval EFI_DEVICE_ERROR     The device reported an error.
> >>>> -  @retval EFI_VOLUME_CORRUPTED The file system structures are
> >>>corrupted.
> >>>> -  @retval EFI_OUT_OF_RESOURCES The scan was not successful due to
> >>>lack of
> >>>> -                               resources.
> >>>> +  @retval EFI_SUCCESS             UDF volume identifiers were
> >>found.
> >>>> +  @retval EFI_NOT_FOUND           UDF volume identifiers were not
> >>>found.
> >>>> +  @retval other                   Failed to perform disk I/O.
> >>>>
> >>>>  **/
> >>>>  EFI_STATUS
> >>>> -SupportUdfFileSystem (
> >>>> +FindUdfVolumeIdentifiers (
> >>>>    IN EFI_BLOCK_IO_PROTOCOL  *BlockIo,
> >>>>    IN EFI_DISK_IO_PROTOCOL   *DiskIo
> >>>>    )
> >>>> @@ -128,7 +127,6 @@ SupportUdfFileSystem (
> >>>>    UINT64                                EndDiskOffset;
> >>>>    CDROM_VOLUME_DESCRIPTOR               VolDescriptor;
> >>>>    CDROM_VOLUME_DESCRIPTOR               TerminatingVolDescriptor;
> >>>> -  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  AnchorPoint;
> >>>>
> >>>>    ZeroMem ((VOID *)&TerminatingVolDescriptor, sizeof
> >>>> (CDROM_VOLUME_DESCRIPTOR));
> >>>>
> >>>> @@ -167,7 +165,7 @@ SupportUdfFileSystem (
> >>>>          (CompareMem ((VOID *)&VolDescriptor,
> >>>>                       (VOID *)&TerminatingVolDescriptor,
> >>>>                       sizeof (CDROM_VOLUME_DESCRIPTOR)) == 0)) {
> >>>> -      return EFI_UNSUPPORTED;
> >>>> +      return EFI_NOT_FOUND;
> >>>>      }
> >>>>    }
> >>>>
> >>>> @@ -176,7 +174,7 @@ SupportUdfFileSystem (
> >>>>    //
> >>>>    Offset += UDF_LOGICAL_SECTOR_SIZE;
> >>>>    if (Offset >= EndDiskOffset) {
> >>>> -    return EFI_UNSUPPORTED;
> >>>> +    return EFI_NOT_FOUND;
> >>>>    }
> >>>>
> >>>>    Status = DiskIo->ReadDisk (
> >>>> @@ -196,7 +194,7 @@ SupportUdfFileSystem (
> >>>>        (CompareMem ((VOID *)VolDescriptor.Unknown.Id,
> >>>>                     (VOID *)UDF_NSR3_IDENTIFIER,
> >>>>                     sizeof (VolDescriptor.Unknown.Id)) != 0)) {
> >>>> -    return EFI_UNSUPPORTED;
> >>>> +    return EFI_NOT_FOUND;
> >>>>    }
> >>>>
> >>>>    //
> >>>> @@ -204,7 +202,7 @@ SupportUdfFileSystem (
> >>>>    //
> >>>>    Offset += UDF_LOGICAL_SECTOR_SIZE;
> >>>>    if (Offset >= EndDiskOffset) {
> >>>> -    return EFI_UNSUPPORTED;
> >>>> +    return EFI_NOT_FOUND;
> >>>>    }
> >>>>
> >>>>    Status = DiskIo->ReadDisk (
> >>>> @@ -221,15 +219,291 @@ SupportUdfFileSystem (
> >>>>    if (CompareMem ((VOID *)VolDescriptor.Unknown.Id,
> >>>>                    (VOID *)UDF_TEA_IDENTIFIER,
> >>>>                    sizeof (VolDescriptor.Unknown.Id)) != 0) {
> >>>> -    return EFI_UNSUPPORTED;
> >>>> +    return EFI_NOT_FOUND;
> >>>> +  }
> >>>> +
> >>>> +  return EFI_SUCCESS;
> >>>> +}
> >>>> +
> >>>> +/**
> >>>> +  Check if Logical Volume Descriptor is supported by current EDK2
> >>>UDF file
> >>>> +  system implementation.
> >>>> +
> >>>> +  @param[in]  LogicalVolDesc  Logical Volume Descriptor pointer.
> >>>> +
> >>>> +  @retval TRUE                Logical Volume Descriptor is
> >>>supported.
> >>>> +  @retval FALSE               Logical Volume Descriptor is not
> >>>supported.
> >>>> +
> >>>> +**/
> >>>> +BOOLEAN
> >>>> +IsLogicalVolumeDescriptorSupported (
> >>>> +  UDF_LOGICAL_VOLUME_DESCRIPTOR *LogicalVolDesc
> >>>> +  )
> >>>> +{
> >>>> +  //
> >>>> +  // Check for a valid UDF revision range
> >>>> +  //
> >>>> +  switch (UDF_LVD_REVISION (LogicalVolDesc)) {
> >>>> +  case 0x0102:
> >>>> +  case 0x0150:
> >>>> +  case 0x0200:
> >>>> +  case 0x0201:
> >>>> +  case 0x0250:
> >>>> +  case 0x0260:
> >>>> +    break;
> >>>> +  default:
> >>>> +    return FALSE;
> >>>> +  }
> >>>> +
> >>>> +  //
> >>>> +  // Check for a single Partition Map  //  if
> >>>> + (LogicalVolDesc->NumberOfPartitionMaps > 1) {
> >>>> +    return FALSE;
> >>>> +  }
> >>>> +  //
> >>>> +  // UDF 1.02 revision supports only Type 1 (Physical) partitions,
> >>>but
> >>>> +  // let's check it any way.
> >>>> +  //
> >>>> +  // PartitionMap[0] -> type
> >>>> +  // PartitionMap[1] -> length (in bytes)  //  if
> >>>> + (LogicalVolDesc->PartitionMaps[0] != 1 ||
> >>>> +      LogicalVolDesc->PartitionMaps[1] != 6) {
> >>>> +    return FALSE;
> >>>> +  }
> >>>> +
> >>>> +  return TRUE;
> >>>> +}
> >>>> +
> >>>> +/**
> >>>> +  Find UDF logical volume location and whether it is supported by
> >>>current EDK2
> >>>> +  UDF file system implementation.
> >>>> +
> >>>> +  @param[in]  BlockIo             BlockIo interface.
> >>>> +  @param[in]  DiskIo              DiskIo interface.
> >>>> +  @param[in]  AnchorPoint         Anchor volume descriptor pointer.
> >>>> +  @param[out] MainVdsStartBlock   Main VDS starting block number.
> >>>> +  @param[out] MainVdsEndBlock     Main VDS ending block number.
> >>>> +
> >>>> +  @retval EFI_SUCCESS             UDF logical volume was found.
> >>>> +  @retval EFI_VOLUME_CORRUPTED    UDF file system structures are
> >>>> corrupted.
> >>>> +  @retval EFI_UNSUPPORTED         UDF logical volume is not
> >>>supported.
> >>>> +  @retval other                   Failed to perform disk I/O.
> >>>> +
> >>>> +**/
> >>>> +EFI_STATUS
> >>>> +FindLogicalVolumeLocation (
> >>>> +  IN   EFI_BLOCK_IO_PROTOCOL                 *BlockIo,
> >>>> +  IN   EFI_DISK_IO_PROTOCOL                  *DiskIo,
> >>>> +  IN   UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint,
> >>>> +  OUT  UINT64                                *MainVdsStartBlock,
> >>>> +  OUT  UINT64                                *MainVdsEndBlock
> >>>> +  )
> >>>> +{
> >>>> +  EFI_STATUS                     Status;
> >>>> +  UINT32                         BlockSize;
> >>>> +  EFI_LBA                        LastBlock;
> >>>> +  UDF_EXTENT_AD                  *ExtentAd;
> >>>> +  UINT64                         SeqBlocksNum;
> >>>> +  UINT64                         SeqStartBlock;
> >>>> +  UINT64                         GuardMainVdsStartBlock;
> >>>> +  VOID                           *Buffer;
> >>>> +  UINT64                         SeqEndBlock;
> >>>> +  BOOLEAN                        StopSequence;
> >>>> +  UINTN                          LvdsCount;
> >>>> +  UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;
> >>>> +  UDF_DESCRIPTOR_TAG             *DescriptorTag;
> >>>> +
> >>>> +  BlockSize = BlockIo->Media->BlockSize;  LastBlock =
> >>>> + BlockIo->Media->LastBlock;  ExtentAd =
> >>>> + &AnchorPoint->MainVolumeDescriptorSequenceExtent;
> >>>> +
> >>>> +  //
> >>>> +  // UDF 2.60, 2.2.3.1 struct MainVolumeDescriptorSequenceExtent
> >>>> +  //
> >>>> +  // The Main Volume Descriptor Sequence Extent shall have a
> >>minimum
> >>>length
> >>>> of
> >>>> +  // 16 logical sectors.
> >>>> +  //
> >>>> +  // Also make sure it does not exceed maximum number of blocks in
> >>>the disk.
> >>>> +  //
> >>>> +  SeqBlocksNum = DivU64x32 ((UINT64)ExtentAd->ExtentLength,
> >>>BlockSize);
> >>>> +  if (SeqBlocksNum < 16 || (EFI_LBA)SeqBlocksNum > LastBlock + 1) {
> >>>> +    return EFI_VOLUME_CORRUPTED;
> >>>> +  }
> >>>> +
> >>>> +  //
> >>>> +  // Check for valid Volume Descriptor Sequence starting block
> >>>number
> >>>> +  //
> >>>> +  SeqStartBlock = (UINT64)ExtentAd->ExtentLocation;  if
> >>>> + (SeqStartBlock > LastBlock ||
> >>>> +      SeqStartBlock + SeqBlocksNum - 1 > LastBlock) {
> >>>> +    return EFI_VOLUME_CORRUPTED;
> >>>>    }
> >>>>
> >>>> +  GuardMainVdsStartBlock = SeqStartBlock;
> >>>> +
> >>>> +  //
> >>>> +  // Allocate buffer for reading disk blocks  //  Buffer =
> >>>> + AllocateZeroPool ((UINTN)BlockSize);  if (Buffer == NULL) {
> >>>> +    return EFI_OUT_OF_RESOURCES;
> >>>> +  }
> >>>> +
> >>>> +  SeqEndBlock = SeqStartBlock + SeqBlocksNum;  StopSequence =
> >>FALSE;
> >>>> + LvdsCount = 0;  Status = EFI_VOLUME_CORRUPTED;  //  // Start Main
> >>>> + Volume Descriptor Sequence  //  for (; SeqStartBlock <
> >>>> + SeqEndBlock
> >>
> >>>> + && !StopSequence;
> >>>SeqStartBlock++) {
> >>>> +    //
> >>>> +    // Read disk block
> >>>> +    //
> >>>> +    Status = BlockIo->ReadBlocks (
> >>>> +      BlockIo,
> >>>> +      BlockIo->Media->MediaId,
> >>>> +      SeqStartBlock,
> >>>> +      BlockSize,
> >>>> +      Buffer
> >>>> +      );
> >>>> +    if (EFI_ERROR (Status)) {
> >>>> +      goto Out_Free;
> >>>> +    }
> >>>> +
> >>>> +    DescriptorTag = Buffer;
> >>>> +
> >>>> +    //
> >>>> +    // ECMA 167, 8.4.1 Contents of a Volume Descriptor Sequence
> >>>> +    //
> >>>> +    // - A Volume Descriptor Sequence shall contain one or more
> >>>Primary
> >>>> Volume
> >>>> +    //   Descriptors.
> >>>> +    // - A Volume Descriptor Sequence shall contain zero or more
> >>>> Implementation
> >>>> +    //   Use Volume Descriptors.
> >>>> +    // - A Volume Descriptor Sequence shall contain zero or more
> >>>Partition
> >>>> +    //   Descriptors.
> >>>> +    // - A Volume Descriptor Sequence shall contain zero or more
> >>>Logical
> >>>> Volume
> >>>> +    //   Descriptors.
> >>>> +    // - A Volume Descriptor Sequence shall contain zero or more
> >>>Unallocated
> >>>> +    //   Space Descriptors.
> >>>> +    //
> >>>> +    switch (UDF_TAG_ID (DescriptorTag)) {
> >>>> +    case UdfPrimaryVolumeDescriptor:
> >>>> +    case UdfImplemenationUseVolumeDescriptor:
> >>>> +    case UdfPartitionDescriptor:
> >>>> +    case UdfUnallocatedSpaceDescriptor:
> >>>> +      break;
> >>>> +
> >>>> +    case UdfLogicalVolumeDescriptor:
> >>>> +      LogicalVolDesc = Buffer;
> >>>> +
> >>>> +      //
> >>>> +      // Check for existence of a single LVD and whether it is
> >>>supported by
> >>>> +      // current EDK2 UDF file system implementation.
> >>>> +      //
> >>>> +      if (++LvdsCount > 1 ||
> >>>> +          !IsLogicalVolumeDescriptorSupported (LogicalVolDesc)) {
> >>>> +        Status = EFI_UNSUPPORTED;
> >>>> +        StopSequence = TRUE;
> >>>> +      }
> >>>> +
> >>>> +      break;
> >>>> +
> >>>> +    case UdfTerminatingDescriptor:
> >>>> +      //
> >>>> +      // Stop the sequence when we find a Terminating Descriptor
> >>>> +      // (aka Unallocated Sector), se we don't have to walk all
> >>>> + the
> >>>unallocated
> >>>> +      // area unnecessarily.
> >>>> +      //
> >>>> +      StopSequence = TRUE;
> >>>> +      break;
> >>>> +
> >>>> +    default:
> >>>> +      //
> >>>> +      // An invalid Volume Descriptor has been found in the
> >>sequece.
> >>>Volume is
> >>>> +      // corrupted.
> >>>> +      //
> >>>> +      Status = EFI_VOLUME_CORRUPTED;
> >>>> +      goto Out_Free;
> >>>> +    }
> >>>> +  }
> >>>> +
> >>>> +  //
> >>>> +  // Check if LVD was found
> >>>> +  //
> >>>> +  if (!EFI_ERROR (Status) && LvdsCount == 1) {
> >>>> +    *MainVdsStartBlock = GuardMainVdsStartBlock;
> >>>> +    //
> >>>> +    // We do not need to read either LVD or PD descriptors to know
> >>>the last
> >>>> +    // valid block in the found UDF file system. It's already
> >>>LastBlock.
> >>>> +    //
> >>>> +    *MainVdsEndBlock = LastBlock;
> >>>> +
> >>>> +    Status = EFI_SUCCESS;
> >>>> +  }
> >>>> +
> >>>> +Out_Free:
> >>>> +  //
> >>>> +  // Free block read buffer
> >>>> +  //
> >>>> +  FreePool (Buffer);
> >>>> +
> >>>> +  return Status;
> >>>> +}
> >>>> +
> >>>> +/**
> >>>> +  Find a supported UDF file system in block device.
> >>>> +
> >>>> +  @param[in]  BlockIo             BlockIo interface.
> >>>> +  @param[in]  DiskIo              DiskIo interface.
> >>>> +  @param[out] StartingLBA         UDF file system starting LBA.
> >>>> +  @param[out] EndingLBA           UDF file system starting LBA.
> >>>> +
> >>>> +  @retval EFI_SUCCESS             UDF file system was found.
> >>>> +  @retval other                   UDF file system was not found.
> >>>> +
> >>>> +**/
> >>>> +EFI_STATUS
> >>>> +FindUdfFileSystem (
> >>>> +  IN EFI_BLOCK_IO_PROTOCOL  *BlockIo,
> >>>> +  IN EFI_DISK_IO_PROTOCOL   *DiskIo,
> >>>> +  OUT EFI_LBA               *StartingLBA,
> >>>> +  OUT EFI_LBA               *EndingLBA
> >>>> +  )
> >>>> +{
> >>>> +  EFI_STATUS Status;
> >>>> +  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  AnchorPoint;
> >>>> +
> >>>> +  //
> >>>> +  // Find UDF volume identifiers
> >>>> +  //
> >>>> +  Status = FindUdfVolumeIdentifiers (BlockIo, DiskIo);  if
> >>>> + (EFI_ERROR (Status)) {
> >>>> +    return Status;
> >>>> +  }
> >>>> +
> >>>> +  //
> >>>> +  // Find Anchor Volume Descriptor Pointer  //
> >>>>    Status = FindAnchorVolumeDescriptorPointer (BlockIo, DiskIo,
> >>>&AnchorPoint);
> >>>>    if (EFI_ERROR (Status)) {
> >>>> -    return EFI_UNSUPPORTED;
> >>>> +    return Status;
> >>>>    }
> >>>>
> >>>> -  return EFI_SUCCESS;
> >>>> +  //
> >>>> +  // Find Logical Volume location
> >>>> +  //
> >>>> +  Status = FindLogicalVolumeLocation (
> >>>> +    BlockIo,
> >>>> +    DiskIo,
> >>>> +    &AnchorPoint,
> >>>> +    (UINT64 *)StartingLBA,
> >>>> +    (UINT64 *)EndingLBA
> >>>> +    );
> >>>> +
> >>>> +  return Status;
> >>>>  }
> >>>>
> >>>>  /**
> >>>> @@ -263,9 +537,9 @@ PartitionInstallUdfChildHandles (
> >>>>    UINT32                       RemainderByMediaBlockSize;
> >>>>    EFI_STATUS                   Status;
> >>>>    EFI_BLOCK_IO_MEDIA           *Media;
> >>>> -  EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode;
> >>>> -  EFI_GUID                     *VendorDefinedGuid;
> >>>>    EFI_PARTITION_INFO_PROTOCOL  PartitionInfo;
> >>>> +  EFI_LBA                      StartingLBA;
> >>>> +  EFI_LBA                      EndingLBA;
> >>>>
> >>>>    Media = BlockIo->Media;
> >>>>
> >>>> @@ -281,35 +555,10 @@ PartitionInstallUdfChildHandles (
> >>>>      return EFI_NOT_FOUND;
> >>>>    }
> >>>>
> >>>> -  DevicePathNode = DevicePath;
> >>>> -  while (!IsDevicePathEnd (DevicePathNode)) {
> >>>> -    //
> >>>> -    // Do not allow checking for UDF file systems in CDROM "El
> >>>Torito"
> >>>> -    // partitions, and skip duplicate installation of UDF file
> >>>system child
> >>>> -    // nodes.
> >>>> -    //
> >>>> -    if (DevicePathType (DevicePathNode) == MEDIA_DEVICE_PATH) {
> >>>> -      if (DevicePathSubType (DevicePathNode) == MEDIA_CDROM_DP) {
> >>>> -        return EFI_NOT_FOUND;
> >>>> -      }
> >>>> -      if (DevicePathSubType (DevicePathNode) == MEDIA_VENDOR_DP)
> {
> >>>> -        VendorDefinedGuid = (EFI_GUID *)((UINTN)DevicePathNode +
> >>>> -                                         OFFSET_OF
> >>>(VENDOR_DEVICE_PATH, Guid));
> >>>> -        if (CompareGuid (VendorDefinedGuid, &gUdfDevPathGuid)) {
> >>>> -          return EFI_NOT_FOUND;
> >>>> -        }
> >>>> -      }
> >>>> -    }
> >>>> -    //
> >>>> -    // Try next device path node
> >>>> -    //
> >>>> -    DevicePathNode = NextDevicePathNode (DevicePathNode);
> >>>> -  }
> >>>> -
> >>>>    //
> >>>> -  // Check if block device supports an UDF file system
> >>>> +  // Search for an UDF file system on block device
> >>>>    //
> >>>> -  Status = SupportUdfFileSystem (BlockIo, DiskIo);
> >>>> +  Status = FindUdfFileSystem (BlockIo, DiskIo, &StartingLBA,
> >>>&EndingLBA);
> >>>>    if (EFI_ERROR (Status)) {
> >>>>      return EFI_NOT_FOUND;
> >>>>    }
> >>>> @@ -334,8 +583,8 @@ PartitionInstallUdfChildHandles (
> >>>>      DevicePath,
> >>>>      (EFI_DEVICE_PATH_PROTOCOL *)&gUdfDevicePath,
> >>>>      &PartitionInfo,
> >>>> -    0,
> >>>> -    Media->LastBlock,
> >>>> +    StartingLBA,
> >>>> +    EndingLBA,
> >>>>      Media->BlockSize
> >>>>      );
> >>>>    if (!EFI_ERROR (Status)) {
> >>>> diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/File.c
> >>>> b/MdeModulePkg/Universal/Disk/UdfDxe/File.c
> >>>> index 625f2c5637..6f07bf2066 100644
> >>>> --- a/MdeModulePkg/Universal/Disk/UdfDxe/File.c
> >>>> +++ b/MdeModulePkg/Universal/Disk/UdfDxe/File.c
> >>>> @@ -131,7 +131,6 @@ Error_Alloc_Priv_File_Data:
> >>>>    CleanupFileInformation (&PrivFsData->Root);
> >>>>
> >>>>  Error_Find_Root_Dir:
> >>>> -  CleanupVolumeInformation (&PrivFsData->Volume);
> >>>>
> >>>>  Error_Read_Udf_Volume:
> >>>>  Error_Invalid_Params:
> >>>> @@ -429,7 +428,7 @@ UdfRead (
> >>>>      }
> >>>>      ASSERT (NewFileEntryData != NULL);
> >>>>
> >>>> -    if (IS_FE_SYMLINK (NewFileEntryData)) {
> >>>> +    if (FE_ICB_FILE_TYPE (NewFileEntryData) ==
> >>>> + UdfFileEntrySymlink)
> >>>{
> >>>>        Status = ResolveSymlink (
> >>>>          BlockIo,
> >>>>          DiskIo,
> >>>> @@ -529,7 +528,6 @@ UdfClose (
> >>>>    EFI_TPL                     OldTpl;
> >>>>    EFI_STATUS                  Status;
> >>>>    PRIVATE_UDF_FILE_DATA       *PrivFileData;
> >>>> -  PRIVATE_UDF_SIMPLE_FS_DATA  *PrivFsData;
> >>>>
> >>>>    OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
> >>>>
> >>>> @@ -542,8 +540,6 @@ UdfClose (
> >>>>
> >>>>    PrivFileData = PRIVATE_UDF_FILE_DATA_FROM_THIS (This);
> >>>>
> >>>> -  PrivFsData = PRIVATE_UDF_SIMPLE_FS_DATA_FROM_THIS
> (PrivFileData-
> >>>> >SimpleFs);
> >>>> -
> >>>>    if (!PrivFileData->IsRootDirectory) {
> >>>>      CleanupFileInformation (&PrivFileData->File);
> >>>>
> >>>> @@ -552,10 +548,6 @@ UdfClose (
> >>>>      }
> >>>>    }
> >>>>
> >>>> -  if (--PrivFsData->OpenFiles == 0) {
> >>>> -    CleanupVolumeInformation (&PrivFsData->Volume);
> >>>> -  }
> >>>> -
> >>>>    FreePool ((VOID *)PrivFileData);
> >>>>
> >>>>  Exit:
> >>>> @@ -652,7 +644,7 @@ UdfGetPosition (
> >>>>    // As per UEFI spec, if the file handle is a directory, then the
> >>>current file
> >>>>    // position has no meaning and the operation is not supported.
> >>>>    //
> >>>> -  if (IS_FID_DIRECTORY_FILE
> >>>(&PrivFileData->File.FileIdentifierDesc)) {
> >>>> +  if (IS_FID_DIRECTORY_FILE
> >>(PrivFileData->File.FileIdentifierDesc))
> >>>{
> >>>>      return  EFI_UNSUPPORTED;
> >>>>    }
> >>>>
> >>>> @@ -788,7 +780,7 @@ UdfGetInfo (
> >>>>    } else if (CompareGuid (InformationType,
> >>&gEfiFileSystemInfoGuid))
> >>>{
> >>>>      String = VolumeLabel;
> >>>>
> >>>> -    FileSetDesc = PrivFsData->Volume.FileSetDescs[0];
> >>>> +    FileSetDesc = &PrivFsData->Volume.FileSetDesc;
> >>>>
> >>>>      OstaCompressed = &FileSetDesc->LogicalVolumeIdentifier[0];
> >>>>
> >>>> @@ -847,7 +839,7 @@ UdfGetInfo (
> >>>>      FileSystemInfo->Size        = FileSystemInfoLength;
> >>>>      FileSystemInfo->ReadOnly    = TRUE;
> >>>>      FileSystemInfo->BlockSize   =
> >>>> -      LV_BLOCK_SIZE (&PrivFsData->Volume, UDF_DEFAULT_LV_NUM);
> >>>> +      PrivFsData->Volume.LogicalVolDesc.LogicalBlockSize;
> >>>>      FileSystemInfo->VolumeSize  = VolumeSize;
> >>>>      FileSystemInfo->FreeSpace   = FreeSpaceSize;
> >>>>
> >>>> diff --git
> >>>a/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
> >>>> b/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
> >>>> index 5df267761f..62d817989f 100644
> >>>> --- a/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
> >>>> +++
> b/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
> >>>> @@ -38,11 +38,12 @@ FindAnchorVolumeDescriptorPointer (
> >>>>    OUT  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint
> >>>>    )
> >>>>  {
> >>>> -  EFI_STATUS  Status;
> >>>> -  UINT32      BlockSize;
> >>>> -  EFI_LBA     EndLBA;
> >>>> -  EFI_LBA     DescriptorLBAs[4];
> >>>> -  UINTN       Index;
> >>>> +  EFI_STATUS          Status;
> >>>> +  UINT32              BlockSize;
> >>>> +  EFI_LBA             EndLBA;
> >>>> +  EFI_LBA             DescriptorLBAs[4];
> >>>> +  UINTN               Index;
> >>>> +  UDF_DESCRIPTOR_TAG  *DescriptorTag;
> >>>>
> >>>>    BlockSize = BlockIo->Media->BlockSize;
> >>>>    EndLBA = BlockIo->Media->LastBlock; @@ -62,10 +63,13 @@
> >>>> FindAnchorVolumeDescriptorPointer (
> >>>>      if (EFI_ERROR (Status)) {
> >>>>        return Status;
> >>>>      }
> >>>> +
> >>>> +    DescriptorTag = &AnchorPoint->DescriptorTag;
> >>>> +
> >>>>      //
> >>>>      // Check if read LBA has a valid AVDP descriptor.
> >>>>      //
> >>>> -    if (IS_AVDP (AnchorPoint)) {
> >>>> +    if (DescriptorTag->TagIdentifier ==
> >>>UdfAnchorVolumeDescriptorPointer) {
> >>>>        return EFI_SUCCESS;
> >>>>      }
> >>>>    }
> >>>> @@ -99,148 +103,98 @@ StartMainVolumeDescriptorSequence (
> >>>>    OUT  UDF_VOLUME_INFO                       *Volume
> >>>>    )
> >>>>  {
> >>>> -  EFI_STATUS                     Status;
> >>>> -  UINT32                         BlockSize;
> >>>> -  UDF_EXTENT_AD                  *ExtentAd;
> >>>> -  UINT64                         StartingLsn;
> >>>> -  UINT64                         EndingLsn;
> >>>> -  VOID                           *Buffer;
> >>>> -  UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;
> >>>> -  UDF_PARTITION_DESCRIPTOR       *PartitionDesc;
> >>>> -  UINTN                          Index;
> >>>> -  UINT32                         LogicalBlockSize;
> >>>> +  EFI_STATUS            Status;
> >>>> +  UINT32                BlockSize;
> >>>> +  UDF_EXTENT_AD         *ExtentAd;
> >>>> +  EFI_LBA               SeqStartBlock;
> >>>> +  EFI_LBA               SeqEndBlock;
> >>>> +  BOOLEAN               StopSequence;
> >>>> +  VOID                  *Buffer;
> >>>> +  UDF_DESCRIPTOR_TAG    *DescriptorTag;
> >>>> +  UINT32                LogicalBlockSize;
> >>>> +
> >>>> +  BlockSize = BlockIo->Media->BlockSize;  ExtentAd =
> >>>> + &AnchorPoint->MainVolumeDescriptorSequenceExtent;
> >>>>
> >>>>    //
> >>>> -  // We've already found an ADVP on the volume. It contains the
> >>>extent
> >>>> -  // (MainVolumeDescriptorSequenceExtent) where the Main Volume
> >>>> Descriptor
> >>>> -  // Sequence starts. Therefore, we'll look for Logical Volume
> >>>Descriptors and
> >>>> -  // Partitions Descriptors and save them in memory, accordingly.
> >>>> -  //
> >>>> -  // Note also that each descriptor will be aligned on a block
> >>>> size
> >>>(BlockSize)
> >>>> -  // boundary, so we need to read one block at a time.
> >>>> +  // Allocate buffer for reading disk blocks
> >>>>    //
> >>>> -  BlockSize    = BlockIo->Media->BlockSize;
> >>>> -  ExtentAd     = &AnchorPoint-
> >MainVolumeDescriptorSequenceExtent;
> >>>> -  StartingLsn  = (UINT64)ExtentAd->ExtentLocation;
> >>>> -  EndingLsn    = StartingLsn + DivU64x32 (
> >>>> -
> >>(UINT64)ExtentAd->ExtentLength,
> >>>> -                                     BlockSize
> >>>> -                                     );
> >>>> -
> >>>> -  Volume->LogicalVolDescs =
> >>>> -    (UDF_LOGICAL_VOLUME_DESCRIPTOR **)AllocateZeroPool
> (ExtentAd-
> >>>> >ExtentLength);
> >>>> -  if (Volume->LogicalVolDescs == NULL) {
> >>>> -    return EFI_OUT_OF_RESOURCES;
> >>>> -  }
> >>>> -
> >>>> -  Volume->PartitionDescs =
> >>>> -    (UDF_PARTITION_DESCRIPTOR **)AllocateZeroPool (ExtentAd-
> >>>> >ExtentLength);
> >>>> -  if (Volume->PartitionDescs == NULL) {
> >>>> -    Status = EFI_OUT_OF_RESOURCES;
> >>>> -    goto Error_Alloc_Pds;
> >>>> -  }
> >>>> -
> >>>> -  Buffer = AllocateZeroPool (BlockSize);
> >>>> +  Buffer = AllocateZeroPool ((UINTN)BlockSize);
> >>>>    if (Buffer == NULL) {
> >>>> -    Status = EFI_OUT_OF_RESOURCES;
> >>>> -    goto Error_Alloc_Buf;
> >>>> +    return EFI_OUT_OF_RESOURCES;
> >>>>    }
> >>>>
> >>>> -  Volume->LogicalVolDescsNo  = 0;
> >>>> -  Volume->PartitionDescsNo   = 0;
> >>>> -
> >>>> -  while (StartingLsn <= EndingLsn) {
> >>>> -    Status = DiskIo->ReadDisk (
> >>>> -      DiskIo,
> >>>> +  //
> >>>> +  // The logical partition created by Partition driver is relative
> >>>to the main
> >>>> +  // VDS extent location, so we start the Main Volume Descriptor
> >>>Sequence at
> >>>> +  // LBA 0.
> >>>> +  //
> >>>> +  // We don't need to check again if we have valid Volume
> >>>Descriptors here
> >>>> since
> >>>> +  // Partition driver already did.
> >>>> +  //
> >>>> +  SeqStartBlock = 0;
> >>>> +  SeqEndBlock = SeqStartBlock + DivU64x32
> >>>((UINT64)ExtentAd->ExtentLength,
> >>>> +                                           BlockSize);
> >>StopSequence
> >>>> + = FALSE;  for (; SeqStartBlock < SeqEndBlock && !StopSequence;
> >>>SeqStartBlock++) {
> >>>> +    //
> >>>> +    // Read disk block
> >>>> +    //
> >>>> +    Status = BlockIo->ReadBlocks (
> >>>> +      BlockIo,
> >>>>        BlockIo->Media->MediaId,
> >>>> -      MultU64x32 (StartingLsn, BlockSize),
> >>>> +      SeqStartBlock,
> >>>>        BlockSize,
> >>>>        Buffer
> >>>>        );
> >>>>      if (EFI_ERROR (Status)) {
> >>>> -      goto Error_Read_Disk_Blk;
> >>>> +      goto Out_Free;
> >>>>      }
> >>>>
> >>>> -    if (IS_TD (Buffer)) {
> >>>> +    DescriptorTag = Buffer;
> >>>> +
> >>>> +    switch (UDF_TAG_ID (DescriptorTag)) {
> >>>> +    case UdfPartitionDescriptor:
> >>>>        //
> >>>> -      // Found a Terminating Descriptor. Stop the sequence then.
> >>>> +      // Save Partition Descriptor
> >>>>        //
> >>>> +      CopyMem (&Volume->PartitionDesc, Buffer, sizeof (Volume-
> >>>> >PartitionDesc));
> >>>>        break;
> >>>> -    }
> >>>>
> >>>> -    if (IS_LVD (Buffer)) {
> >>>> +    case UdfLogicalVolumeDescriptor:
> >>>>        //
> >>>> -      // Found a Logical Volume Descriptor.
> >>>> +      // Save Logical Volume Descriptor
> >>>>        //
> >>>> -      LogicalVolDesc =
> >>>> -        (UDF_LOGICAL_VOLUME_DESCRIPTOR *)
> >>>> -        AllocateZeroPool (sizeof (UDF_LOGICAL_VOLUME_DESCRIPTOR));
> >>>> -      if (LogicalVolDesc == NULL) {
> >>>> -        Status = EFI_OUT_OF_RESOURCES;
> >>>> -        goto Error_Alloc_Lvd;
> >>>> -      }
> >>>> +      CopyMem (&Volume->LogicalVolDesc, Buffer, sizeof (Volume-
> >>>> >LogicalVolDesc));
> >>>> +      break;
> >>>>
> >>>> -      CopyMem ((VOID *)LogicalVolDesc, Buffer,
> >>>> -               sizeof (UDF_LOGICAL_VOLUME_DESCRIPTOR));
> >>>> -      Volume->LogicalVolDescs[Volume->LogicalVolDescsNo++] =
> >>>> LogicalVolDesc;
> >>>> -    } else if (IS_PD (Buffer)) {
> >>>> -      //
> >>>> -      // Found a Partition Descriptor.
> >>>> -      //
> >>>> -      PartitionDesc =
> >>>> -        (UDF_PARTITION_DESCRIPTOR *)
> >>>> -        AllocateZeroPool (sizeof (UDF_PARTITION_DESCRIPTOR));
> >>>> -      if (PartitionDesc == NULL) {
> >>>> -        Status = EFI_OUT_OF_RESOURCES;
> >>>> -        goto Error_Alloc_Pd;
> >>>> -      }
> >>>> +    case UdfTerminatingDescriptor:
> >>>> +      StopSequence = TRUE;
> >>>> +      break;
> >>>>
> >>>> -      CopyMem ((VOID *)PartitionDesc, Buffer,
> >>>> -               sizeof (UDF_PARTITION_DESCRIPTOR));
> >>>> -      Volume->PartitionDescs[Volume->PartitionDescsNo++] =
> >>>PartitionDesc;
> >>>> +    default:
> >>>> +      ;
> >>>>      }
> >>>> -
> >>>> -    StartingLsn++;
> >>>>    }
> >>>>
> >>>>    //
> >>>> -  // When an UDF volume (revision 2.00 or higher) contains a File
> >>>Entry rather
> >>>> -  // than an Extended File Entry (which is not recommended as per
> >>>spec), we
> >>>> need
> >>>> -  // to make sure the size of a FE will be _at least_ 2048
> >>>> -  // (UDF_LOGICAL_SECTOR_SIZE) bytes long to keep backward
> >>>compatibility.
> >>>> +  // Determine FE (File Entry) size
> >>>>    //
> >>>> -  LogicalBlockSize = LV_BLOCK_SIZE (Volume,
> UDF_DEFAULT_LV_NUM);
> >>>> +  LogicalBlockSize = Volume->LogicalVolDesc.LogicalBlockSize;
> >>>>    if (LogicalBlockSize >= UDF_LOGICAL_SECTOR_SIZE) {
> >>>> -    Volume->FileEntrySize = LogicalBlockSize;
> >>>> +    Volume->FileEntrySize = (UINTN)LogicalBlockSize;
> >>>>    } else {
> >>>>      Volume->FileEntrySize = UDF_LOGICAL_SECTOR_SIZE;
> >>>>    }
> >>>>
> >>>> -  FreePool (Buffer);
> >>>> +  Status = EFI_SUCCESS;
> >>>>
> >>>> -  return EFI_SUCCESS;
> >>>> -
> >>>> -Error_Alloc_Pd:
> >>>> -Error_Alloc_Lvd:
> >>>> -  for (Index = 0; Index < Volume->PartitionDescsNo; Index++) {
> >>>> -    FreePool ((VOID *)Volume->PartitionDescs[Index]);
> >>>> -  }
> >>>> -
> >>>> -  for (Index = 0; Index < Volume->LogicalVolDescsNo; Index++) {
> >>>> -    FreePool ((VOID *)Volume->LogicalVolDescs[Index]);
> >>>> -  }
> >>>> -
> >>>> -Error_Read_Disk_Blk:
> >>>> +Out_Free:
> >>>> +  //
> >>>> +  // Free block read buffer
> >>>> +  //
> >>>>    FreePool (Buffer);
> >>>>
> >>>> -Error_Alloc_Buf:
> >>>> -  FreePool ((VOID *)Volume->PartitionDescs);
> >>>> -  Volume->PartitionDescs = NULL;
> >>>> -
> >>>> -Error_Alloc_Pds:
> >>>> -  FreePool ((VOID *)Volume->LogicalVolDescs);
> >>>> -  Volume->LogicalVolDescs = NULL;
> >>>> -
> >>>>    return Status;
> >>>>  }
> >>>>
> >>>> @@ -262,48 +216,53 @@ GetPdFromLongAd (
> >>>>    )
> >>>>  {
> >>>>    UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;
> >>>> -  UINTN                          Index;
> >>>> -  UDF_PARTITION_DESCRIPTOR       *PartitionDesc;
> >>>>    UINT16                         PartitionNum;
> >>>>
> >>>> -  LogicalVolDesc = Volume->LogicalVolDescs[UDF_DEFAULT_LV_NUM];
> >>>> +  LogicalVolDesc = &Volume->LogicalVolDesc;
> >>>>
> >>>> -  switch (LV_UDF_REVISION (LogicalVolDesc)) {
> >>>> +  switch (UDF_LVD_REVISION (LogicalVolDesc)) {
> >>>>    case 0x0102:
> >>>> +  case 0x0150:
> >>>> +  case 0x0200:
> >>>> +  case 0x0201:
> >>>> +  case 0x0250:
> >>>> +  case 0x0260:
> >>>>      //
> >>>> -    // As per UDF 1.02 specification:
> >>>> +    // UDF 1.02 specification:
> >>>>      //
> >>>>      // There shall be exactly one prevailing Logical Volume
> >>>Descriptor recorded
> >>>>      // per Volume Set. The Partition Maps field shall contain only
> >>>Type 1
> >>>>      // Partition Maps.
> >>>>      //
> >>>> -    PartitionNum = *(UINT16
> >>>*)((UINTN)&LogicalVolDesc->PartitionMaps[4]);
> >>>> -    break;
> >>>> -  case 0x0150:
> >>>> +    // UDF 1.50 through 2.60 specs say:
> >>>>      //
> >>>> -    // Ensure Type 1 Partition map. Other types aren't supported in
> >>>this
> >>>> -    // implementation.
> >>>> +    // For the purpose of interchange partition maps shall be
> >>>limited to
> >>>> +    // Partition Map type 1, except type 2 maps as described in
> >>>> + the
> >>>document.
> >>>> +    //
> >>>> +    // NOTE: Only one Type 1 (Physical) Partition is supported. It
> >>>has been
> >>>> +    // checked already in Partition driver for existence of a
> >>single
> >>>Type 1
> >>>> +    // Partition map, so we don't have to double check here.
> >>>> +    //
> >>>> +    // Partition reference number can also be retrieved from
> >>>> +    // LongAd->ExtentLocation.PartitionReferenceNumber, however
> >>>> + the
> >>>spec
> >>>> says
> >>>> +    // it may be 0, so let's not rely on it.
> >>>>      //
> >>>> -    if (LogicalVolDesc->PartitionMaps[0] != 1 ||
> >>>> -        LogicalVolDesc->PartitionMaps[1] != 6) {
> >>>> -      return NULL;
> >>>> -    }
> >>>>      PartitionNum = *(UINT16
> >>>*)((UINTN)&LogicalVolDesc->PartitionMaps[4]);
> >>>>      break;
> >>>> -  case 0x0260:
> >>>> +
> >>>> +  default:
> >>>>      //
> >>>> -    // Fall through.
> >>>> +    // Unsupported UDF revision
> >>>>      //
> >>>> -  default:
> >>>> -    PartitionNum = LongAd->ExtentLocation.PartitionReferenceNumber;
> >>>> -    break;
> >>>> +    return NULL;
> >>>>    }
> >>>>
> >>>> -
> >
> > --
> > Sent from my Android device with K-9 Mail. Please excuse my brevity.
> > _______________________________________________
> > edk2-devel mailing list
> > edk2-devel@lists.01.org
> > https://lists.01.org/mailman/listinfo/edk2-devel
> 
> 
> 
> --
> Paulo Alcantara, HP
> Speaking for myself only.
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel