主卷描述符用来标识一个卷以及这个卷的特定属性。主卷描述符结构如下
/* Primary Volume Descriptor (ECMA 167r3 3/10.1) */ struct primaryVolDesc { struct tag descTag; __le32 volDescSeqNum; __le32 primaryVolDescNum; dstring volIdent[32]; __le16 volSeqNum; __le16 maxVolSeqNum; __le16 interchangeLvl; __le16 maxInterchangeLvl; __le32 charSetList; __le32 maxCharSetList; dstring volSetIdent[128]; struct charspec descCharSet; struct charspec explanatoryCharSet; struct extent_ad volAbstract; struct extent_ad volCopyright; struct regid appIdent; struct timestamp recordingDateAndTime; struct regid impIdent; uint8_t impUse[64]; __le32 predecessorVolDescSeqLocation; __le16 flags; uint8_t reserved[22]; } __attribute__ ((packed));
@volDescSeqNum 描述符的卷描述符序列号
@primaryVolDescNum 主卷描述符号
@volIdent 卷标识符
@volSeqNum 如果这个卷是卷集合的成员,那么volSeqNum表示这个卷在卷集合中的序号
@maxVolSeqNum 标识了当前这个描述符被记录时,所在卷集合的最大卷序列号。
@interchangeLvl 这个卷的当前介质交换级别。
@maxInterchangeLvl 这个卷所支持的最大介质交换级别
@charSetList 这个描述符中所有成员使用的字符集列表
@maxCharSetList,charSetList中使用的字符集不应该超出这个@maxCharSetList
@volSetIdent,卷所在卷集合的标识符
@descCharSet,标识在volSetIdent和volIdent中允许使用的字符集
@explanatoryCharset,描述了Volume adstract和Volume copyright notice扩展的字符集
@volAdstract,描述了包含volume abstract sectors所在的extent位置。如果extent的长度为0,那么没有volume abstract
@volCopyright,描述了包含copyright notice所在的extent的位置。如果extent长度为0,那么没有copyright notice
@appIdent,应用标识。如果这个成员的内容都为#00,那么表示没有应用
@recordingDataAndTime,指明这个描述符记录的日期和时间。
@impIdent,实现标识,
@impUse,为实现使用保留的成员,本文档不定义它的内容。
@predecessorVolDescSeqLocation,标识卷描述符所在extent之前的逻辑sectors所在的extent。如果这个成员为0,表示不存在这个extent。这个extent主要用来做灾难恢复
@flags,这个成员用来表示这个主卷描述符的特定特点。
Anchor卷描述符指针用来标识主卷描述符和保留卷描述符所在的extent,数据结构如下:
struct anchorVolDescPtr { struct tag descTag; struct extent_ad mainVolDescSeqExt; struct extent_ad reserveVolDescSeqExt; uint8_t reserved[480]; } __attribute__ ((packed));
@mainVolDescSeqExt 标识了主要描述符序列所在的extent。这个扩展主要使用来标识可用空间,而不是记录已用空间。
@reserveWolDescSeqExt 标识了保留卷描述符序列所在的extent。这个扩展主要是记录可用空间,而不是记录已用空间。
struct volDescPtr { struct tag descTag; __le32 volDescSeqNum; struct extent_ad nextVolDescSeqExt; uint8_t reserved[484]; } __attribute__ ((packed));
@tag,对于这种描述符,tag的标识为3
@volDescSeqNum,这个描述符的卷描述序列编号
@nextVolDescSeqExt,标识卷描述符序列中的下一个extent。如果extent长度为0,那么没有下一个extent
实现用描述符用来标识一个实现,可以通过这个成员进行识别和操作。
struct impUseVolDesc { struct tag descTag; __le32 volDescSeqNum; struct regid impIdent; uint8_t impUse[460]; } __attribute__ ((packed));
@volDescSeqNum,标识这个描述符的卷描述序列号
@impIdent,用来保存一个实现的标识。
@impUse保留给实现使用,本文当不对内容做规定。
分区描述符用来保存分区的尺寸和位置,记录格式如下:
struct partitionDesc { struct tag descTag; __le32 volDescSeqNum; __le16 partitionFlags; __le16 partitionNumber; struct regid partitionContents; uint8_t partitionContentsUse[128]; __le32 accessType; __le32 partitionStartingLocation; __le32 partitionLength; struct regid impIdent; uint8_t impUse[128]; uint8_t reserved[156]; } __attribute__ ((packed));
@volDescSeqNum,这个描述符的卷描述序列编号
@partitionFlags,标识分区的特定特点
@partitionNumber,分区的数字标识
@partitionContents,一个标识说明如何解释分区的内容。
@partitionContentsUse,记录这个描述符所指分区的内容如何解释的信息。这个成员的内容依赖于分区内容的相应标准
@accessType,这个成员用来标识描述符所之分区的访问方法
@partitionStartingLocation,分区的起始逻辑sectors号
@partitionLength,标识组成这个分区的逻辑sectors数目。
@impIdent,实现标识符,用来识别实现,以及实现时用到的内容
@impUse,保留给实现使用的,在ECMA标准不定义它的内容。
/* Logical Volume Descriptor (ECMA 167r3 3/10.6) */ struct logicalVolDesc { struct tag descTag; __le32 volDescSeqNum; struct charspec descCharSet; dstring logicalVolIdent[128]; __le32 logicalBlockSize; struct regid domainIdent; uint8_t logicalVolContentsUse[16]; __le32 mapTableLength; __le32 numPartitionMaps; struct regid impIdent; uint8_t impUse[128]; struct extent_ad integritySeqExt; uint8_t partitionMaps[0]; } __attribute__ ((packed));
@descTag,对于逻辑卷描述符,tag结构的标识成员值为6
@volDescSeqNum,标识这个描述符的卷描述序列号
@descCharSet,标识逻辑卷标识符所用的字符集
@logicalVolIdent ,逻辑卷的标识
@logicalBlockSize,卷的逻辑块尺寸,bytes
@domainIdent,域描述符,域用来标识使用规则,限制等。如果这个成员全#00,那么没有在domain中。
@logicalVolContentsUse,这个成员标识如何解释记录在这个逻辑卷上的信息。这些信息的定义有相应的文档。
@mapTableLength,定义分区映射的长度。
@numPartitionMaps,标识分区映射的数目
@impIdent,实现标识,用来识别一个实现,以及实现需要使用的内容。如果这个成员全为#00,那么没有实现定义。
@Implementation Use,保留给实现使用,ECMA标准不定义它的内容。
@interitySeqExt,标识逻辑卷完整性序列的第一个extent使用。这个 extent应该在这个描述符所在的卷中。
@PartitionMaps,这个成员包含分区映射,分区影射连续的排列
/* Generic Partition Map (ECMA 167r3 3/10.7.1) */ struct genericPartitionMap { uint8_t partitionMapType; uint8_t partitionMapLength; uint8_t partitionMapping[0]; } __attribute__ ((packed));
@partitionMapType,标识分区映射类型,现支持的分区映射类型为0, 1, 2
@partitionMapLength,分区映射长度,包括分区映射类型以及分区映射长度本身。
@partitionMapLength,对这个成员的解释,需要依赖于分区类型标识的标准和条款,如果分区类型为1,那么就由介质生产者和消费者之间协商得到。
/* Type 1 Partition Map (ECMA 167r3 3/10.7.2) */ struct genericPartitionMap1 { uint8_t partitionMapType; uint8_t partitionMapLength; __le16 volSeqNum; __le16 partitionNum; } __attribute__ ((packed));
@partitionMapType,这个值应该为1
@partitionMapLength,这个值应该为6
@volSeqNum,逻辑卷所在的卷,在某个卷集合中,volSeqNum的值等于这个卷在卷集合中的卷序列号
@partitionNum,这个成员标识一个分区,这个分区存在于volSeqNum标识的卷上,并且分区描述符的分区号等于@partitionNum
/* Type 2 Partition Map (ECMA 167r3 3/10.7.3) */ struct genericPartitionMap2 { uint8_t partitionMapType; uint8_t partitionMapLength; uint8_t partitionIdent[62]; } __attribute__ ((packed));
这个映射类型用来标识介质创建者和接受端达成一致的分区类型。
@partitionMapType,分区类型为2
@partitionMapLength,长度为64
@partitionIdent,分区标识