From: Paulo Alcantara <pcacjr@zytor.com>
To: edk2-devel@lists.01.org
Cc: Paulo Alcantara <pcacjr@zytor.com>,
Eric Dong <eric.dong@intel.com>, Ruiyu Ni <ruiyu.ni@intel.com>,
Star Zeng <star.zeng@intel.com>, Laszlo Ersek <lersek@redhat.com>
Subject: [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix creation of UDF logical partition
Date: Wed, 20 Sep 2017 15:16:23 -0300 [thread overview]
Message-ID: <e969511c03927f9b785ec85b8252d24b593bae2b.1505929933.git.pcacjr@zytor.com> (raw)
In-Reply-To: <cover.1505929933.git.pcacjr@zytor.com>
In-Reply-To: <cover.1505929933.git.pcacjr@zytor.com>
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
next prev parent reply other threads:[~2017-09-20 18:16 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-09-20 18:16 [PATCH v3 0/2] UDF partition driver fix Paulo Alcantara
2017-09-20 18:16 ` [PATCH v3 1/2] MdePkg: Add UDF volume structure definitions Paulo Alcantara
2017-09-22 2:50 ` Ni, Ruiyu
2017-09-22 13:54 ` Paulo Alcantara
2017-09-20 18:16 ` Paulo Alcantara [this message]
2017-09-21 8:08 ` [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix creation of UDF logical partition Wu, Hao A
2017-09-21 8:49 ` Zeng, Star
2017-09-21 13:22 ` Paulo Alcantara
2017-09-21 12:44 ` Wu, Hao A
2017-09-21 13:29 ` Paulo Alcantara
2017-09-21 13:47 ` Zeng, Star
2017-09-21 13:52 ` Paulo Alcantara
2017-09-21 14:16 ` Paulo Alcantara
2017-09-22 2:26 ` Zeng, Star
2017-09-22 2:59 ` Ni, Ruiyu
2017-09-20 19:25 ` [PATCH v3 0/2] UDF partition driver fix Laszlo Ersek
2017-09-20 19:38 ` Paulo Alcantara
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=e969511c03927f9b785ec85b8252d24b593bae2b.1505929933.git.pcacjr@zytor.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox