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
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
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
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
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
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
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
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
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
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
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
© 2016 - 2024 Red Hat, Inc.