* [PATCH v3 0/2] UDF partition driver fix @ 2017-09-20 18:16 Paulo Alcantara 2017-09-20 18:16 ` [PATCH v3 1/2] MdePkg: Add UDF volume structure definitions Paulo Alcantara ` (2 more replies) 0 siblings, 3 replies; 17+ messages in thread From: Paulo Alcantara @ 2017-09-20 18:16 UTC (permalink / raw) To: edk2-devel Cc: Paulo Alcantara, Michael D Kinney, Liming Gao, Laszlo Ersek, Ruiyu Ni, Star Zeng, Jiewen Yao REF: https://bugzilla.tianocore.org/show_bug.cgi?id=707 Hi, This patchset fixes a bug in Partition driver that created UDF logical partitions by using entire block device space and thus polluting protocol database with broken handles. v1->v2: - Followed Laszlo's suggestions to submit a proper patchset. Thanks! - As I'm still waiting for Ruiyu and Star to test this fix, I took advantage of it and did some code cleanups :-) v2->v3: - Followed Ruiyu's suggestions to improve code and add additional checks for ensuring a valid UDF file system and supported by current EDK2 UDF file system implementation. Also run Ecc.py to make sure the files I touched did not break EDK2 C Coding Style, as well as PatchCheck.py for mal-formed patches. I've had a chance to test these changes with my 32GiB USB stick and formatted it on Windows 10 with `format` command. The UDF revisions I tested (by specifying it with "/R:revision") were 1.02, 1.50, 2.00, 2.01 (default) and 2.50. They all worked except the 2.50 revision which adds a Type 2 (Metadata) Partition and it's not supported by current EDK2 UDF implementation -- which handles only Type 1 (Physical) Partitions. The UDF 2.60 revision I tested with the usual `sudo mkudffs -b 512 --media-type=hd /dev/sdX` command in Linux. Remember, the *officially* supported revision is 2.60, however all revisions use the same volume structures as defined by ECMA 167 specification, and they usually differ from each other by means of new optional features, so that's why all those revisions worked with this implementation. Well, at least this what I understood when looking at the specifications. Please correct me if I'm wrong. Please, test building these changes in toolchains other than GCC and make sure they don't break the world :-) Thanks! Paulo Repo: https://github.com/pcacjr/edk2.git Branch: udf-partition-fix-v3 Cc: Michael D Kinney <michael.d.kinney@intel.com> Cc: Liming Gao <liming.gao@intel.com> Cc: Laszlo Ersek <lersek@redhat.com> Cc: Ruiyu Ni <ruiyu.ni@intel.com> Cc: Star Zeng <star.zeng@intel.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Contributed-under: TianoCore Contribution Agreement 1.1 Reported-by: Ruiyu Ni <ruiyu.ni@intel.com> Signed-off-by: Paulo Alcantara <pcacjr@zytor.com> --- Paulo Alcantara (2): MdePkg: Add UDF volume structure definitions MdeModulePkg/PartitionDxe: Fix creation of UDF logical partition 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 ++--- MdePkg/Include/IndustryStandard/Udf.h | 63 +- 6 files changed, 665 insertions(+), 569 deletions(-) -- 2.11.0 ^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v3 1/2] MdePkg: Add UDF volume structure definitions 2017-09-20 18:16 [PATCH v3 0/2] UDF partition driver fix Paulo Alcantara @ 2017-09-20 18:16 ` Paulo Alcantara 2017-09-22 2:50 ` Ni, Ruiyu 2017-09-20 18:16 ` [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix creation of UDF logical partition Paulo Alcantara 2017-09-20 19:25 ` [PATCH v3 0/2] UDF partition driver fix Laszlo Ersek 2 siblings, 1 reply; 17+ messages in thread From: Paulo Alcantara @ 2017-09-20 18:16 UTC (permalink / raw) To: edk2-devel Cc: Paulo Alcantara, Michael D Kinney, Liming Gao, Laszlo Ersek, Ruiyu Ni This patch adds a few more UDF volume structures in order to detect an UDF file system which is supported by current EDK2 UDF file system implementation in Partition driver. Cc: Michael D Kinney <michael.d.kinney@intel.com> Cc: Liming Gao <liming.gao@intel.com> Cc: Laszlo Ersek <lersek@redhat.com> Cc: Ruiyu Ni <ruiyu.ni@intel.com> Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Paulo Alcantara <pcacjr@zytor.com> --- MdePkg/Include/IndustryStandard/Udf.h | 63 ++++++++++++++++++-- 1 file changed, 59 insertions(+), 4 deletions(-) diff --git a/MdePkg/Include/IndustryStandard/Udf.h b/MdePkg/Include/IndustryStandard/Udf.h index 0febb4bcda..002e87e150 100644 --- a/MdePkg/Include/IndustryStandard/Udf.h +++ b/MdePkg/Include/IndustryStandard/Udf.h @@ -24,11 +24,28 @@ #define UDF_LOGICAL_SECTOR_SIZE ((UINT64)(1ULL << UDF_LOGICAL_SECTOR_SHIFT)) #define UDF_VRS_START_OFFSET ((UINT64)(16ULL << UDF_LOGICAL_SECTOR_SHIFT)) -#define _GET_TAG_ID(_Pointer) \ - (((UDF_DESCRIPTOR_TAG *)(_Pointer))->TagIdentifier) +typedef enum { + UdfPrimaryVolumeDescriptor = 1, + UdfAnchorVolumeDescriptorPointer = 2, + UdfVolumeDescriptorPointer = 3, + UdfImplemenationUseVolumeDescriptor = 4, + UdfPartitionDescriptor = 5, + UdfLogicalVolumeDescriptor = 6, + UdfUnallocatedSpaceDescriptor = 7, + UdfTerminatingDescriptor = 8, + UdfLogicalVolumeIntegrityDescriptor = 9, + UdfFileSetDescriptor = 256, + UdfFileIdentifierDescriptor = 257, + UdfAllocationExtentDescriptor = 258, + UdfFileEntry = 261, + UdfExtendedFileEntry = 266, +} UDF_VOLUME_DESCRIPTOR_ID; -#define IS_AVDP(_Pointer) \ - ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 2)) +#define UDF_TAG_ID(_Tag) \ + (UDF_VOLUME_DESCRIPTOR_ID)((_Tag)->TagIdentifier) + +#define UDF_LVD_REVISION(_Lv) \ + *(UINT16 *)(UINTN)(_Lv)->DomainIdentifier.IdentifierSuffix #pragma pack(1) @@ -49,12 +66,50 @@ typedef struct { } UDF_EXTENT_AD; 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 { + 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; UDF_EXTENT_AD MainVolumeDescriptorSequenceExtent; UDF_EXTENT_AD ReserveVolumeDescriptorSequenceExtent; UINT8 Reserved[480]; } UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER; +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; + #pragma pack() #endif -- 2.11.0 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH v3 1/2] MdePkg: Add UDF volume structure definitions 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 0 siblings, 1 reply; 17+ messages in thread From: Ni, Ruiyu @ 2017-09-22 2:50 UTC (permalink / raw) To: Paulo Alcantara, edk2-devel@lists.01.org Cc: Kinney, Michael D, Gao, Liming, Laszlo Ersek Paulo, Comments below: #define UDF_TAG_ID(_Tag) \ (UDF_VOLUME_DESCRIPTOR_ID)((_Tag)->TagIdentifier) 1. I prefer to remove the UDF_TAG_ID macro. Adding type-cast to get TAG_ID is very straightforward. #define UDF_LVD_REVISION(_Lv) \ *(UINT16 *)(UINTN)(_Lv)->DomainIdentifier.IdentifierSuffix typedef struct { UINT8 Flags; UINT8 Identifier[23]; UINT8 IdentifierSuffix[8]; } UDF_ENTITY_ID; 2. Entity structure is defined by ECMA-167 spec and re-used by UDF spec. I think since we are creating UDF structure in udf.h, how about using the below structure layout and removing the UDF_LVD_REVISION macro: Typedef struct { UINT8 Flags; UINT8 Identifier[23]; UINT16 UdfRevision; UINT8 DomainFlags; UINT8 Reserved[5]; } UDF_ENTITY_ID; I am not sure if there are other structures that are defined in ECMA spec and re-used by UDF spec. I think we can apply the similar rules to those structures as well. Thanks/Ray > -----Original Message----- > From: Paulo Alcantara [mailto:pcacjr@zytor.com] > Sent: Thursday, September 21, 2017 2:16 AM > To: edk2-devel@lists.01.org > Cc: Paulo Alcantara <pcacjr@zytor.com>; Kinney, Michael D > <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>; Laszlo > Ersek <lersek@redhat.com>; Ni, Ruiyu <ruiyu.ni@intel.com> > Subject: [PATCH v3 1/2] MdePkg: Add UDF volume structure definitions > > This patch adds a few more UDF volume structures in order to detect an UDF > file system which is supported by current EDK2 UDF file system > implementation in Partition driver. > > Cc: Michael D Kinney <michael.d.kinney@intel.com> > Cc: Liming Gao <liming.gao@intel.com> > Cc: Laszlo Ersek <lersek@redhat.com> > Cc: Ruiyu Ni <ruiyu.ni@intel.com> > Contributed-under: TianoCore Contribution Agreement 1.1 > Signed-off-by: Paulo Alcantara <pcacjr@zytor.com> > --- > MdePkg/Include/IndustryStandard/Udf.h | 63 ++++++++++++++++++-- > 1 file changed, 59 insertions(+), 4 deletions(-) > > diff --git a/MdePkg/Include/IndustryStandard/Udf.h > b/MdePkg/Include/IndustryStandard/Udf.h > index 0febb4bcda..002e87e150 100644 > --- a/MdePkg/Include/IndustryStandard/Udf.h > +++ b/MdePkg/Include/IndustryStandard/Udf.h > @@ -24,11 +24,28 @@ > #define UDF_LOGICAL_SECTOR_SIZE ((UINT64)(1ULL << > UDF_LOGICAL_SECTOR_SHIFT)) > #define UDF_VRS_START_OFFSET ((UINT64)(16ULL << > UDF_LOGICAL_SECTOR_SHIFT)) > > -#define _GET_TAG_ID(_Pointer) \ > - (((UDF_DESCRIPTOR_TAG *)(_Pointer))->TagIdentifier) > +typedef enum { > + UdfPrimaryVolumeDescriptor = 1, > + UdfAnchorVolumeDescriptorPointer = 2, > + UdfVolumeDescriptorPointer = 3, > + UdfImplemenationUseVolumeDescriptor = 4, > + UdfPartitionDescriptor = 5, > + UdfLogicalVolumeDescriptor = 6, > + UdfUnallocatedSpaceDescriptor = 7, > + UdfTerminatingDescriptor = 8, > + UdfLogicalVolumeIntegrityDescriptor = 9, > + UdfFileSetDescriptor = 256, > + UdfFileIdentifierDescriptor = 257, > + UdfAllocationExtentDescriptor = 258, > + UdfFileEntry = 261, > + UdfExtendedFileEntry = 266, > +} UDF_VOLUME_DESCRIPTOR_ID; > > -#define IS_AVDP(_Pointer) \ > - ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 2)) > +#define UDF_TAG_ID(_Tag) \ > + (UDF_VOLUME_DESCRIPTOR_ID)((_Tag)->TagIdentifier) > + > +#define UDF_LVD_REVISION(_Lv) \ > + *(UINT16 *)(UINTN)(_Lv)->DomainIdentifier.IdentifierSuffix > > #pragma pack(1) > > @@ -49,12 +66,50 @@ typedef struct { > } UDF_EXTENT_AD; > > 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 { > + 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; > UDF_EXTENT_AD MainVolumeDescriptorSequenceExtent; > UDF_EXTENT_AD ReserveVolumeDescriptorSequenceExtent; > UINT8 Reserved[480]; > } UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER; > > +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; > + > #pragma pack() > > #endif > -- > 2.11.0 ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v3 1/2] MdePkg: Add UDF volume structure definitions 2017-09-22 2:50 ` Ni, Ruiyu @ 2017-09-22 13:54 ` Paulo Alcantara 0 siblings, 0 replies; 17+ messages in thread From: Paulo Alcantara @ 2017-09-22 13:54 UTC (permalink / raw) To: Ni, Ruiyu, edk2-devel@lists.01.org Cc: Kinney, Michael D, Gao, Liming, Laszlo Ersek Ruiyu, On 9/21/2017 11:50 PM, Ni, Ruiyu wrote: > Paulo, > Comments below: > > #define UDF_TAG_ID(_Tag) \ > (UDF_VOLUME_DESCRIPTOR_ID)((_Tag)->TagIdentifier) > 1. I prefer to remove the UDF_TAG_ID macro. Adding type-cast to get TAG_ID is very straightforward. Right. I'll remove it. > > #define UDF_LVD_REVISION(_Lv) \ > *(UINT16 *)(UINTN)(_Lv)->DomainIdentifier.IdentifierSuffix > typedef struct { > UINT8 Flags; > UINT8 Identifier[23]; > UINT8 IdentifierSuffix[8]; > } UDF_ENTITY_ID; > 2. Entity structure is defined by ECMA-167 spec and re-used by UDF spec. > I think since we are creating UDF structure in udf.h, how about using the below > structure layout and removing the UDF_LVD_REVISION macro: > Typedef struct { > UINT8 Flags; > UINT8 Identifier[23]; > UINT16 UdfRevision; > UINT8 DomainFlags; > UINT8 Reserved[5]; > } UDF_ENTITY_ID; Much better! Thanks for looking into that. The UDF 2.60 specification says: > UDF classifies Entity Identifiers into 4 separate types. Each type has > its own Suffix Type for the Identifier Suffix field. The 4 types are: > > Domain Entity Identifiers with a Domain Identifier Suffix > UDF Entity Identifiers with a UDF Identifier Suffix > Implementation Entity Identifiers with an Implementation Identifier Suffix > Application Entity Identifiers with an Application Identifier Suffix Given that, I think an union would be more appropriate. E.g., typedef struct { UINT8 Flags; UINT8 Identifier[23]; union { struct { UINT16 UdfRevision; UINT8 DomainFlags; UINT8 Reversed[5]; } DomainIdentifier; struct { UINT16 UdfRevision; UINT8 OSClass; UINT8 OSIdentifier; UINT8 Reserved[4]; } EntityIdentifier; struct { UINT8 OSClass; UINT8 OSIdentifier; UINT8 ImplementationUseArea[6]; } ImplementationEntityIdentifier; struct { UINT8 ApplicationUseArea[8]; } ApplicationEntityIdentifier; UINT8 IdentifierSuffix[8]; }; } UDF_ENTITY_ID; Do you agree with me? Or that wouldn't be necessary? Thanks! Paulo > > I am not sure if there are other structures that are defined in ECMA spec and > re-used by UDF spec. I think we can apply the similar rules to those structures > as well. > > Thanks/Ray > >> -----Original Message----- >> From: Paulo Alcantara [mailto:pcacjr@zytor.com] >> Sent: Thursday, September 21, 2017 2:16 AM >> To: edk2-devel@lists.01.org >> Cc: Paulo Alcantara <pcacjr@zytor.com>; Kinney, Michael D >> <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>; Laszlo >> Ersek <lersek@redhat.com>; Ni, Ruiyu <ruiyu.ni@intel.com> >> Subject: [PATCH v3 1/2] MdePkg: Add UDF volume structure definitions >> >> This patch adds a few more UDF volume structures in order to detect an UDF >> file system which is supported by current EDK2 UDF file system >> implementation in Partition driver. >> >> Cc: Michael D Kinney <michael.d.kinney@intel.com> >> Cc: Liming Gao <liming.gao@intel.com> >> Cc: Laszlo Ersek <lersek@redhat.com> >> Cc: Ruiyu Ni <ruiyu.ni@intel.com> >> Contributed-under: TianoCore Contribution Agreement 1.1 >> Signed-off-by: Paulo Alcantara <pcacjr@zytor.com> >> --- >> MdePkg/Include/IndustryStandard/Udf.h | 63 ++++++++++++++++++-- >> 1 file changed, 59 insertions(+), 4 deletions(-) >> >> diff --git a/MdePkg/Include/IndustryStandard/Udf.h >> b/MdePkg/Include/IndustryStandard/Udf.h >> index 0febb4bcda..002e87e150 100644 >> --- a/MdePkg/Include/IndustryStandard/Udf.h >> +++ b/MdePkg/Include/IndustryStandard/Udf.h >> @@ -24,11 +24,28 @@ >> #define UDF_LOGICAL_SECTOR_SIZE ((UINT64)(1ULL << >> UDF_LOGICAL_SECTOR_SHIFT)) >> #define UDF_VRS_START_OFFSET ((UINT64)(16ULL << >> UDF_LOGICAL_SECTOR_SHIFT)) >> >> -#define _GET_TAG_ID(_Pointer) \ >> - (((UDF_DESCRIPTOR_TAG *)(_Pointer))->TagIdentifier) >> +typedef enum { >> + UdfPrimaryVolumeDescriptor = 1, >> + UdfAnchorVolumeDescriptorPointer = 2, >> + UdfVolumeDescriptorPointer = 3, >> + UdfImplemenationUseVolumeDescriptor = 4, >> + UdfPartitionDescriptor = 5, >> + UdfLogicalVolumeDescriptor = 6, >> + UdfUnallocatedSpaceDescriptor = 7, >> + UdfTerminatingDescriptor = 8, >> + UdfLogicalVolumeIntegrityDescriptor = 9, >> + UdfFileSetDescriptor = 256, >> + UdfFileIdentifierDescriptor = 257, >> + UdfAllocationExtentDescriptor = 258, >> + UdfFileEntry = 261, >> + UdfExtendedFileEntry = 266, >> +} UDF_VOLUME_DESCRIPTOR_ID; >> >> -#define IS_AVDP(_Pointer) \ >> - ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 2)) >> +#define UDF_TAG_ID(_Tag) \ >> + (UDF_VOLUME_DESCRIPTOR_ID)((_Tag)->TagIdentifier) >> + >> +#define UDF_LVD_REVISION(_Lv) \ >> + *(UINT16 *)(UINTN)(_Lv)->DomainIdentifier.IdentifierSuffix >> >> #pragma pack(1) >> >> @@ -49,12 +66,50 @@ typedef struct { >> } UDF_EXTENT_AD; >> >> 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 { >> + 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; >> UDF_EXTENT_AD MainVolumeDescriptorSequenceExtent; >> UDF_EXTENT_AD ReserveVolumeDescriptorSequenceExtent; >> UINT8 Reserved[480]; >> } UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER; >> >> +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; >> + >> #pragma pack() >> >> #endif >> -- >> 2.11.0 > > ^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix creation of UDF logical partition 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-20 18:16 ` Paulo Alcantara 2017-09-21 8:08 ` Wu, Hao A 2017-09-21 12:44 ` Wu, Hao A 2017-09-20 19:25 ` [PATCH v3 0/2] UDF partition driver fix Laszlo Ersek 2 siblings, 2 replies; 17+ messages in thread From: Paulo Alcantara @ 2017-09-20 18:16 UTC (permalink / raw) To: edk2-devel; +Cc: Paulo Alcantara, Eric Dong, Ruiyu Ni, Star Zeng, Laszlo Ersek 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 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix creation of UDF logical partition 2017-09-20 18:16 ` [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix creation of UDF logical partition Paulo Alcantara @ 2017-09-21 8:08 ` Wu, Hao A 2017-09-21 8:49 ` Zeng, Star 2017-09-21 12:44 ` Wu, Hao A 1 sibling, 1 reply; 17+ messages in thread From: Wu, Hao A @ 2017-09-21 8:08 UTC (permalink / raw) To: Paulo Alcantara, edk2-devel@lists.01.org Cc: Ni, Ruiyu, Laszlo Ersek, Dong, Eric, Zeng, Star 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 ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix creation of UDF logical partition 2017-09-21 8:08 ` Wu, Hao A @ 2017-09-21 8:49 ` Zeng, Star 2017-09-21 13:22 ` Paulo Alcantara 0 siblings, 1 reply; 17+ messages in thread From: Zeng, Star @ 2017-09-21 8:49 UTC (permalink / raw) To: Wu, Hao A, Paulo Alcantara, edk2-devel@lists.01.org Cc: Ni, Ruiyu, Laszlo Ersek, Dong, Eric, Zeng, Star 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 ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix creation of UDF logical partition 2017-09-21 8:49 ` Zeng, Star @ 2017-09-21 13:22 ` Paulo Alcantara 0 siblings, 0 replies; 17+ messages in thread From: Paulo Alcantara @ 2017-09-21 13:22 UTC (permalink / raw) To: Zeng, Star, Wu, Hao A, edk2-devel@lists.01.org Cc: Ni, Ruiyu, Laszlo Ersek, Dong, Eric 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. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix creation of UDF logical partition 2017-09-20 18:16 ` [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix creation of UDF logical partition Paulo Alcantara 2017-09-21 8:08 ` Wu, Hao A @ 2017-09-21 12:44 ` Wu, Hao A 2017-09-21 13:29 ` Paulo Alcantara 1 sibling, 1 reply; 17+ messages in thread From: Wu, Hao A @ 2017-09-21 12:44 UTC (permalink / raw) To: Paulo Alcantara, edk2-devel@lists.01.org Cc: Ni, Ruiyu, Laszlo Ersek, Dong, Eric, Zeng, Star 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 ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix creation of UDF logical partition 2017-09-21 12:44 ` Wu, Hao A @ 2017-09-21 13:29 ` Paulo Alcantara 2017-09-21 13:47 ` Zeng, Star 0 siblings, 1 reply; 17+ messages in thread From: Paulo Alcantara @ 2017-09-21 13:29 UTC (permalink / raw) To: Wu, Hao A, edk2-devel@lists.01.org Cc: Ni, Ruiyu, Laszlo Ersek, Dong, Eric, Zeng, Star 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. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix creation of UDF logical partition 2017-09-21 13:29 ` Paulo Alcantara @ 2017-09-21 13:47 ` Zeng, Star 2017-09-21 13:52 ` Paulo Alcantara 0 siblings, 1 reply; 17+ messages in thread From: Zeng, Star @ 2017-09-21 13:47 UTC (permalink / raw) To: Paulo Alcantara, Wu, Hao A, edk2-devel@lists.01.org Cc: Ni, Ruiyu, Laszlo Ersek, Dong, Eric, Zeng, Star 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. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix creation of UDF logical partition 2017-09-21 13:47 ` Zeng, Star @ 2017-09-21 13:52 ` Paulo Alcantara 2017-09-21 14:16 ` Paulo Alcantara 0 siblings, 1 reply; 17+ messages in thread From: Paulo Alcantara @ 2017-09-21 13:52 UTC (permalink / raw) To: Zeng, Star, Wu, Hao A, edk2-devel@lists.01.org Cc: Ni, Ruiyu, Laszlo Ersek, Dong, Eric 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. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix creation of UDF logical partition 2017-09-21 13:52 ` Paulo Alcantara @ 2017-09-21 14:16 ` Paulo Alcantara 2017-09-22 2:26 ` Zeng, Star 0 siblings, 1 reply; 17+ messages in thread From: Paulo Alcantara @ 2017-09-21 14:16 UTC (permalink / raw) To: Zeng, Star, Wu, Hao A, edk2-devel@lists.01.org Cc: Ni, Ruiyu, Laszlo Ersek, Dong, Eric 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. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix creation of UDF logical partition 2017-09-21 14:16 ` Paulo Alcantara @ 2017-09-22 2:26 ` Zeng, Star 2017-09-22 2:59 ` Ni, Ruiyu 0 siblings, 1 reply; 17+ messages in thread From: Zeng, Star @ 2017-09-22 2:26 UTC (permalink / raw) To: Paulo Alcantara, Wu, Hao A, edk2-devel@lists.01.org Cc: Ni, Ruiyu, Laszlo Ersek, Dong, Eric, Zeng, Star 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. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix creation of UDF logical partition 2017-09-22 2:26 ` Zeng, Star @ 2017-09-22 2:59 ` Ni, Ruiyu 0 siblings, 0 replies; 17+ messages in thread From: Ni, Ruiyu @ 2017-09-22 2:59 UTC (permalink / raw) To: Zeng, Star, Paulo Alcantara, Wu, Hao A, edk2-devel@lists.01.org Cc: Laszlo Ersek, Dong, Eric 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. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v3 0/2] UDF partition driver fix 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-20 18:16 ` [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix creation of UDF logical partition Paulo Alcantara @ 2017-09-20 19:25 ` Laszlo Ersek 2017-09-20 19:38 ` Paulo Alcantara 2 siblings, 1 reply; 17+ messages in thread From: Laszlo Ersek @ 2017-09-20 19:25 UTC (permalink / raw) To: Paulo Alcantara, edk2-devel Cc: Ruiyu Ni, Liming Gao, Michael D Kinney, Jiewen Yao, Star Zeng On 09/20/17 20:16, Paulo Alcantara wrote: > Please, test building these changes in toolchains other than GCC and > make sure they don't break the world :-) > Repo: https://github.com/pcacjr/edk2.git > Branch: udf-partition-fix-v3 I build-tested your branch with OVMF (both IA32 and X64), using: - gcc-4.8.5, GCC48, DEBUG - clang-3.8.1, CLANG38, NOOPT - gcc-7.1.1, GCC5, DEBUG and also cross-built your branch as part of ArmVirtQemu (both ARM and AARCH64), using: - gcc-6.1.1, GCC5, DEBUG If it matters, you can add: Build-tested-by: Laszlo Ersek <lersek@redhat.com> Thanks! Laszlo ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v3 0/2] UDF partition driver fix 2017-09-20 19:25 ` [PATCH v3 0/2] UDF partition driver fix Laszlo Ersek @ 2017-09-20 19:38 ` Paulo Alcantara 0 siblings, 0 replies; 17+ messages in thread From: Paulo Alcantara @ 2017-09-20 19:38 UTC (permalink / raw) To: Laszlo Ersek, edk2-devel Cc: Ruiyu Ni, Liming Gao, Michael D Kinney, Jiewen Yao, Star Zeng On September 20, 2017 4:25:10 PM GMT-03:00, Laszlo Ersek <lersek@redhat.com> wrote: >On 09/20/17 20:16, Paulo Alcantara wrote: > >> Please, test building these changes in toolchains other than GCC and >> make sure they don't break the world :-) > >> Repo: https://github.com/pcacjr/edk2.git >> Branch: udf-partition-fix-v3 > >I build-tested your branch with OVMF (both IA32 and X64), using: > >- gcc-4.8.5, GCC48, DEBUG >- clang-3.8.1, CLANG38, NOOPT >- gcc-7.1.1, GCC5, DEBUG > >and also cross-built your branch as part of ArmVirtQemu (both ARM and >AARCH64), using: > >- gcc-6.1.1, GCC5, DEBUG > >If it matters, you can add: > >Build-tested-by: Laszlo Ersek <lersek@redhat.com> Of course it does! :-) Thank you very much. You might be wondering why I didn't build-test it with MSVC - well, my wife's laptop got no Visual Studio installed, bul only the necessary 'format' command for formatting my USB stick with UDF :-) Thanks! Paulo -- Sent from my Android device with K-9 Mail. Please excuse my brevity. ^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2017-09-22 13:53 UTC | newest] Thread overview: 17+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 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 ` [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix creation of UDF logical partition Paulo Alcantara 2017-09-21 8:08 ` 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
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox