| 1 | /*	$OpenBSD: ecma167-udf.h,v 1.10 2022/01/11 03:13:59 jsg Exp $	*/ |
| 2 | /* $NetBSD: ecma167-udf.h,v 1.10 2008/06/24 15:30:33 reinoud Exp $ */ |
| 3 | |
| 4 | /*- |
| 5 | * Copyright (c) 2003, 2004, 2005, 2006, 2008 Reinoud Zandijk |
| 6 | * Copyright (c) 2001, 2002 Scott Long <scottl@freebsd.org> |
| 7 | * All rights reserved. |
| 8 | * |
| 9 | * Redistribution and use in source and binary forms, with or without |
| 10 | * modification, are permitted provided that the following conditions |
| 11 | * are met: |
| 12 | * 1. Redistributions of source code must retain the above copyright |
| 13 | * notice, this list of conditions and the following disclaimer. |
| 14 | * 2. Redistributions in binary form must reproduce the above copyright |
| 15 | * notice, this list of conditions and the following disclaimer in the |
| 16 | * documentation and/or other materials provided with the distribution. |
| 17 | * |
| 18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND |
| 19 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
| 22 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| 23 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
| 24 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| 25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| 26 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
| 27 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 28 | * SUCH DAMAGE. |
| 29 | * |
| 30 | * |
| 31 | * Extended and adapted for UDFv2.50+ bij Reinoud Zandijk based on the |
| 32 | * original by Scott Long. |
| 33 | * |
| 34 | * 20030508 Made some small typo and explanatory comments |
| 35 | * 20030510 Added UDF 2.01 structures |
| 36 | * 20030519 Added/correct comments on multi-partitioned logical volume space |
| 37 | * 20050616 Added pseudo overwrite |
| 38 | * 20050624 Added the missing extended attribute types and `magic values'. |
| 39 | * 20051106 Reworked some implementation use parts |
| 40 | * |
| 41 | */ |
| 42 | |
| 43 | |
| 44 | #ifndef _FS_UDF_ECMA167_UDF_H_ |
| 45 | #define _FS_UDF_ECMA167_UDF_H_ |
| 46 | |
| 47 | |
| 48 | /* ecma167-udf.h */ |
| 49 | |
| 50 | /* Volume recognition sequence ECMA 167 rev. 3 16.1 */ |
| 51 | struct vrs_desc { |
| 52 | 	uint8_t			struct_type; |
| 53 | 	uint8_t			identifier[5]; |
| 54 | 	uint8_t			version; |
| 55 | 	uint8_t			data[2041]; |
| 56 | } __packed; |
| 57 | |
| 58 | |
| 59 | #define VRS_NSR02		"NSR02" |
| 60 | #define VRS_NSR03		"NSR03" |
| 61 | #define VRS_BEA01		"BEA01" |
| 62 | #define VRS_TEA01		"TEA01" |
| 63 | #define VRS_CD001		"CD001" |
| 64 | #define VRS_CDW02		"CDW02" |
| 65 | |
| 66 | |
| 67 | /* Structure/definitions/constants a la ECMA 167 rev. 3 */ |
| 68 | |
| 69 | |
| 70 | #define MAX_TAGID_VOLUMES 9 |
| 71 | /* Tag identifiers */ |
| 72 | enum { |
| 73 | 	TAGID_SPARING_TABLE = 	 0, |
| 74 | 	TAGID_PRI_VOL =		 1, |
| 75 | 	TAGID_ANCHOR =		 2, |
| 76 | 	TAGID_VOL = 		 3, |
| 77 | 	TAGID_IMP_VOL =		 4, |
| 78 | 	TAGID_PARTITION =	 5, |
| 79 | 	TAGID_LOGVOL =		 6, |
| 80 | 	TAGID_UNALLOC_SPACE =	 7, |
| 81 | 	TAGID_TERM =		 8, |
| 82 | 	TAGID_LOGVOL_INTEGRITY=	 9, |
| 83 | 	TAGID_FSD =		256, |
| 84 | 	TAGID_FID =		257, |
| 85 | 	TAGID_ALLOCEXTENT = 	258, |
| 86 | 	TAGID_INDIRECTENTRY =	259, |
| 87 | 	TAGID_ICB_TERM =	260, |
| 88 | 	TAGID_FENTRY =		261, |
| 89 | 	TAGID_EXTATTR_HDR =	262, |
| 90 | 	TAGID_UNALL_SP_ENTRY =	263, |
| 91 | 	TAGID_SPACE_BITMAP = 	264, |
| 92 | 	TAGID_PART_INTEGRITY = 	265, |
| 93 | 	TAGID_EXTFENTRY =	266, |
| 94 | 	TAGID_MAX =		266 |
| 95 | }; |
| 96 | |
| 97 | |
| 98 | enum { |
| 99 | 	UDF_DOMAIN_FLAG_HARD_WRITE_PROTECT = 1, |
| 100 | 	UDF_DOMAIN_FLAG_SOFT_WRITE_PROTECT = 2 |
| 101 | }; |
| 102 | |
| 103 | |
| 104 | enum { |
| 105 | 	UDF_ACCESSTYPE_NOT_SPECIFIED = 0,	/* unknown				*/ |
| 106 | 	UDF_ACCESSTYPE_PSEUDO_OVERWITE = 0,	/* pseudo overwritable, e.g. BD-R's LOW */ |
| 107 | 	UDF_ACCESSTYPE_READ_ONLY = 1,	/* really only readable			*/ |
| 108 | 	UDF_ACCESSTYPE_WRITE_ONCE = 2,	/* write once and you're done		*/ |
| 109 | 	UDF_ACCESSTYPE_REWRITABLE = 3,	/* may need extra work to rewrite	*/ |
| 110 | 	UDF_ACCESSTYPE_OVERWRITABLE = 4	/* no limits on rewriting; e.g. harddisc*/ |
| 111 | }; |
| 112 | |
| 113 | |
| 114 | /* Descriptor tag [3/7.2] */ |
| 115 | struct desc_tag { |
| 116 | 	uint16_t	id; |
| 117 | 	uint16_t	descriptor_ver; |
| 118 | 	uint8_t		cksum; |
| 119 | 	uint8_t		reserved; |
| 120 | 	uint16_t	serial_num; |
| 121 | 	uint16_t	desc_crc; |
| 122 | 	uint16_t	desc_crc_len; |
| 123 | 	uint32_t	tag_loc; |
| 124 | } __packed; |
| 125 | #define UDF_DESC_TAG_LENGTH 16 |
| 126 | |
| 127 | |
| 128 | /* Recorded Address [4/7.1] */ |
| 129 | struct lb_addr {			/* within partition space */ |
| 130 | 	uint32_t	lb_num; |
| 131 | 	uint16_t	part_num; |
| 132 | } __packed; |
| 133 | |
| 134 | |
| 135 | /* Extent Descriptor [3/7.1] */ |
| 136 | struct extent_ad { |
| 137 | 	uint32_t	len; |
| 138 | 	uint32_t	loc; |
| 139 | } __packed; |
| 140 | |
| 141 | |
| 142 | /* Short Allocation Descriptor [4/14.14.1] */ |
| 143 | struct short_ad { |
| 144 | 	uint32_t	len; |
| 145 | 	uint32_t	lb_num; |
| 146 | } __packed; |
| 147 | |
| 148 | |
| 149 | /* Long Allocation Descriptor [4/14.14.2] */ |
| 150 | struct UDF_ADImp_use { |
| 151 | 	uint16_t	flags; |
| 152 | 	uint32_t	unique_id; |
| 153 | } __packed; |
| 154 | #define UDF_ADIMP_FLAGS_EXTENT_ERASED 1 |
| 155 | |
| 156 | |
| 157 | struct long_ad { |
| 158 | 	uint32_t	len; |
| 159 | 	struct lb_addr	loc;			/* within a logical volume mapped partition space !! */ |
| 160 | 	union { |
| 161 | 		uint8_t	bytes[6]; |
| 162 | 		struct UDF_ADImp_use im_used; |
| 163 | 	} __packed impl; |
| 164 | } __packed; |
| 165 | #define longad_uniqueid impl.im_used.unique_id |
| 166 | |
| 167 | |
| 168 | /* Extended Allocation Descriptor [4/14.14.3] ; identifies an extent of allocation descriptors ; also in UDF ? */ |
| 169 | struct ext_ad { |
| 170 | 	uint32_t	ex_len; |
| 171 | 	uint32_t	rec_len; |
| 172 | 	uint32_t	inf_len; |
| 173 | 	struct lb_addr	ex_loc; |
| 174 | 	uint8_t		reserved[2]; |
| 175 | } __packed; |
| 176 | |
| 177 | |
| 178 | /* ICB : Information Control Block; positioning */ |
| 179 | union icb { |
| 180 | 	struct short_ad	s_ad; |
| 181 | 	struct long_ad	l_ad; |
| 182 | 	struct ext_ad	e_ad; |
| 183 | } __packed; |
| 184 | |
| 185 | |
| 186 | /* short/long/ext extent have flags encoded in length */ |
| 187 | #define UDF_EXT_ALLOCATED (0<<30) |
| 188 | #define UDF_EXT_FREED (1<<30) |
| 189 | #define UDF_EXT_ALLOCATED_BUT_NOT_USED (1<<30) |
| 190 | #define UDF_EXT_FREE (2<<30) |
| 191 | #define UDF_EXT_REDIRECT (3<<30) |
| 192 | #define UDF_EXT_FLAGS(len) ((len) & (3<<30)) |
| 193 | #define UDF_EXT_LEN(len) ((len) & ((1<<30)-1)) |
| 194 | #define UDF_EXT_MAXLEN ((1<<30)-1) |
| 195 | |
| 196 | |
| 197 | /* Character set spec [1/7.2.1] */ |
| 198 | struct charspec { |
| 199 | 	uint8_t		type; |
| 200 | 	uint8_t		inf[63]; |
| 201 | } __packed; |
| 202 | |
| 203 | |
| 204 | struct pathcomp { |
| 205 | 	uint8_t		type; |
| 206 | 	uint8_t		l_ci; |
| 207 | 	uint16_t	comp_filever; |
| 208 | 	uint8_t		ident[256]; |
| 209 | } __packed; |
| 210 | #define	UDF_PATH_COMP_SIZE 4 |
| 211 | #define UDF_PATH_COMP_RESERVED		0 |
| 212 | #define UDF_PATH_COMP_ROOT		1 |
| 213 | #define UDF_PATH_COMP_MOUNTROOT		2 |
| 214 | #define UDF_PATH_COMP_PARENTDIR		3 |
| 215 | #define UDF_PATH_COMP_CURDIR		4 |
| 216 | #define UDF_PATH_COMP_NAME		5 |
| 217 | |
| 218 | |
| 219 | /* Timestamp [1/7.3] */ |
| 220 | struct timestamp { |
| 221 | 	uint16_t	type_tz; |
| 222 | 	uint16_t	year; |
| 223 | 	uint8_t		month; |
| 224 | 	uint8_t		day; |
| 225 | 	uint8_t		hour; |
| 226 | 	uint8_t		minute; |
| 227 | 	uint8_t		second; |
| 228 | 	uint8_t		centisec; |
| 229 | 	uint8_t		hund_usec; |
| 230 | 	uint8_t		usec; |
| 231 | } __packed; |
| 232 | #define UDF_TIMESTAMP_SIZE 12 |
| 233 | |
| 234 | |
| 235 | /* Entity Identifier [1/7.4] */ |
| 236 | #define	UDF_REGID_ID_SIZE	23 |
| 237 | struct regid { |
| 238 | 	uint8_t		flags; |
| 239 | 	uint8_t		id[UDF_REGID_ID_SIZE]; |
| 240 | 	uint8_t		id_suffix[8]; |
| 241 | } __packed; |
| 242 | |
| 243 | |
| 244 | /* ICB Tag [4/14.6] */ |
| 245 | struct icb_tag { |
| 246 | 	uint32_t	prev_num_dirs; |
| 247 | 	uint16_t	strat_type; |
| 248 | 	uint8_t		strat_param[2]; |
| 249 | 	uint16_t	max_num_entries; |
| 250 | 	uint8_t		reserved; |
| 251 | 	uint8_t		file_type; |
| 252 | 	struct lb_addr	parent_icb; |
| 253 | 	uint16_t	flags; |
| 254 | } __packed; |
| 255 | #define UDF_ICB_TAG_FLAGS_ALLOC_MASK	0x03 |
| 256 | #define UDF_ICB_SHORT_ALLOC		0x00 |
| 257 | #define UDF_ICB_LONG_ALLOC		0x01 |
| 258 | #define UDF_ICB_EXT_ALLOC		0x02 |
| 259 | #define UDF_ICB_INTERN_ALLOC		0x03 |
| 260 | |
| 261 | #define UDF_ICB_TAG_FLAGS_DIRORDERED	(1<< 3) |
| 262 | #define UDF_ICB_TAG_FLAGS_NONRELOC	(1<< 4) |
| 263 | #define UDF_ICB_TAG_FLAGS_CONTIGUOUS	(1<< 9) |
| 264 | #define UDF_ICB_TAG_FLAGS_MULTIPLEVERS	(1<<12) |
| 265 | |
| 266 | #define	UDF_ICB_TAG_FLAGS_SETUID	(1<< 6) |
| 267 | #define	UDF_ICB_TAG_FLAGS_SETGID	(1<< 7) |
| 268 | #define	UDF_ICB_TAG_FLAGS_STICKY	(1<< 8) |
| 269 | |
| 270 | #define UDF_ICB_FILETYPE_UNKNOWN	 0 |
| 271 | #define UDF_ICB_FILETYPE_UNALLOCSPACE	 1 |
| 272 | #define UDF_ICB_FILETYPE_PARTINTEGRITY 2 |
| 273 | #define UDF_ICB_FILETYPE_INDIRECTENTRY	 3 |
| 274 | #define UDF_ICB_FILETYPE_DIRECTORY	 4 |
| 275 | #define UDF_ICB_FILETYPE_RANDOMACCESS	 5 |
| 276 | #define UDF_ICB_FILETYPE_BLOCKDEVICE	 6 |
| 277 | #define UDF_ICB_FILETYPE_CHARDEVICE	 7 |
| 278 | #define UDF_ICB_FILETYPE_EXTATTRREC	 8 |
| 279 | #define UDF_ICB_FILETYPE_FIFO		 9 |
| 280 | #define UDF_ICB_FILETYPE_SOCKET		 10 |
| 281 | #define UDF_ICB_FILETYPE_TERM		 11 |
| 282 | #define UDF_ICB_FILETYPE_SYMLINK	 12 |
| 283 | #define UDF_ICB_FILETYPE_STREAMDIR	 13 |
| 284 | #define UDF_ICB_FILETYPE_VAT		248 |
| 285 | #define UDF_ICB_FILETYPE_REALTIME	249 |
| 286 | #define UDF_ICB_FILETYPE_META_MAIN	250 |
| 287 | #define UDF_ICB_FILETYPE_META_MIRROR	251 |
| 288 | |
| 289 | |
| 290 | /* Anchor Volume Descriptor Pointer [3/10.2] */ |
| 291 | struct anchor_vdp { |
| 292 | 	struct desc_tag		tag; |
| 293 | 	struct extent_ad	main_vds_ex;		/* to main volume descriptor set ; 16 sectors min */ |
| 294 | 	struct extent_ad	reserve_vds_ex;		/* copy of main volume descriptor set ; 16 sectors min */ |
| 295 | } __packed; |
| 296 | |
| 297 | |
| 298 | /* Volume Descriptor Pointer [3/10.3] */ |
| 299 | struct vol_desc_ptr { |
| 300 | 	struct desc_tag		tag;			/* use for extending the volume descriptor space */ |
| 301 | 	uint32_t		vds_number; |
| 302 | 	struct extent_ad	next_vds_ex;		/* points to the next block for volume descriptor space */ |
| 303 | } __packed; |
| 304 | |
| 305 | |
| 306 | /* Primary Volume Descriptor [3/10.1] */ |
| 307 | struct pri_vol_desc { |
| 308 | 	struct desc_tag		tag; |
| 309 | 	uint32_t		seq_num;		/* MAX prevail */ |
| 310 | 	uint32_t		pvd_num;		/* assigned by author; 0 is special as in it may only occur once */ |
| 311 | 	char			vol_id[32];		/* KEY ; main identifier of this disc */ |
| 312 | 	uint16_t		vds_num;		/* volume descriptor number; i.e. what volume number is it */ |
| 313 | 	uint16_t		max_vol_seq;		/* maximum volume descriptor number known */ |
| 314 | 	uint16_t		ichg_lvl; |
| 315 | 	uint16_t		max_ichg_lvl; |
| 316 | 	uint32_t		charset_list; |
| 317 | 	uint32_t		max_charset_list; |
| 318 | 	char			volset_id[128];		/* KEY ; if part of a multi-disc set or a band of volumes */ |
| 319 | 	struct charspec		desc_charset;		/* KEY according to ECMA 167 */ |
| 320 | 	struct charspec		explanatory_charset; |
| 321 | 	struct extent_ad	vol_abstract; |
| 322 | 	struct extent_ad	vol_copyright; |
| 323 | 	struct regid		app_id; |
| 324 | 	struct timestamp	time; |
| 325 | 	struct regid		imp_id; |
| 326 | 	uint8_t			imp_use[64]; |
| 327 | 	uint32_t		prev_vds_loc;		/* location of predecessor _lov ? */ |
| 328 | 	uint16_t		flags;			/* bit 0 : if set indicates volume set name is meaningful */ |
| 329 | 	uint8_t			reserved[22]; |
| 330 | } __packed; |
| 331 | |
| 332 | |
| 333 | /* UDF specific implementation use part of the implementation use volume descriptor */ |
| 334 | struct udf_lv_info { |
| 335 | 	struct charspec		lvi_charset; |
| 336 | 	char			logvol_id[128]; |
| 337 | |
| 338 | 	char			lvinfo1[36]; |
| 339 | 	char			lvinfo2[36]; |
| 340 | 	char			lvinfo3[36]; |
| 341 | |
| 342 | 	struct regid		impl_id; |
| 343 | 	uint8_t			impl_use[128]; |
| 344 | } __packed; |
| 345 | |
| 346 | |
| 347 | /* Implementation use Volume Descriptor */ |
| 348 | struct impvol_desc { |
| 349 | 	struct desc_tag		tag; |
| 350 | 	uint32_t		seq_num; |
| 351 | 	struct regid		impl_id; |
| 352 | 	union { |
| 353 | 		struct udf_lv_info	lv_info; |
| 354 | 		char			impl_use[460]; |
| 355 | 	} __packed _impl_use; |
| 356 | } __packed; |
| 357 | |
| 358 | |
| 359 | /* Logical Volume Descriptor [3/10.6] */ |
| 360 | struct logvol_desc { |
| 361 | 	struct desc_tag		tag; |
| 362 | 	uint32_t		seq_num;		/* MAX prevail */ |
| 363 | 	struct charspec		desc_charset;		/* KEY */ |
| 364 | 	char			logvol_id[128];		/* KEY */ |
| 365 | 	uint32_t		lb_size; |
| 366 | 	struct regid		domain_id; |
| 367 | 	union { |
| 368 | 		struct long_ad	fsd_loc;		/* to fileset descriptor SEQUENCE */ |
| 369 | 		uint8_t		logvol_content_use[16]; |
| 370 | 	} __packed _lvd_use; |
| 371 | 	uint32_t		mt_l;			/* Partition map length */ |
| 372 | 	uint32_t		n_pm;			/* Number of partition maps */ |
| 373 | 	struct regid		imp_id; |
| 374 | 	uint8_t			imp_use[128]; |
| 375 | 	struct extent_ad	integrity_seq_loc; |
| 376 | 	uint8_t			maps[1]; |
| 377 | } __packed; |
| 378 | #define lv_fsd_loc _lvd_use.fsd_loc |
| 379 | |
| 380 | #define UDF_INTEGRITY_OPEN	0 |
| 381 | #define UDF_INTEGRITY_CLOSED	1 |
| 382 | |
| 383 | |
| 384 | #define	UDF_PMAP_SIZE	64 |
| 385 | |
| 386 | /* Type 1 Partition Map [3/10.7.2] */ |
| 387 | struct part_map_1 { |
| 388 | 	uint8_t			type; |
| 389 | 	uint8_t			len; |
| 390 | 	uint16_t		vol_seq_num; |
| 391 | 	uint16_t		part_num; |
| 392 | } __packed; |
| 393 | |
| 394 | |
| 395 | /* Type 2 Partition Map [3/10.7.3] */ |
| 396 | struct part_map_2 { |
| 397 | 	uint8_t			type; |
| 398 | 	uint8_t			len; |
| 399 | 	uint8_t			reserved[2]; |
| 400 | 	struct regid		part_id; |
| 401 | 	uint16_t		vol_seq_num; |
| 402 | 	uint16_t		part_num; |
| 403 | 	uint8_t			reserved2[24]; |
| 404 | } __packed; |
| 405 | |
| 406 | |
| 407 | /* Virtual Partition Map [UDF 2.01/2.2.8] */ |
| 408 | struct part_map_virt { |
| 409 | 	uint8_t			type; |
| 410 | 	uint8_t			len; |
| 411 | 	uint8_t			reserved[2]; |
| 412 | 	struct regid		id; |
| 413 | 	uint16_t		vol_seq_num; |
| 414 | 	uint16_t		part_num; |
| 415 | 	uint8_t			reserved1[24]; |
| 416 | } __packed; |
| 417 | |
| 418 | |
| 419 | /* Sparable Partition Map [UDF 2.01/2.2.9] */ |
| 420 | struct part_map_spare { |
| 421 | 	uint8_t			type; |
| 422 | 	uint8_t			len; |
| 423 | 	uint8_t			reserved[2]; |
| 424 | 	struct regid		id; |
| 425 | 	uint16_t		vol_seq_num; |
| 426 | 	uint16_t		part_num; |
| 427 | 	uint16_t		packet_len; |
| 428 | 	uint8_t			n_st;		/* Number of redundant sparing tables range 1-4 */ |
| 429 | 	uint8_t			reserved1; |
| 430 | 	uint32_t		st_size;	/* size of EACH sparing table */ |
| 431 | 	uint32_t		st_loc[1];	/* locations of sparing tables */ |
| 432 | } __packed; |
| 433 | |
| 434 | |
| 435 | /* Metadata Partition Map [UDF 2.50/2.2.10] */ |
| 436 | struct part_map_meta { |
| 437 | 	uint8_t			type; |
| 438 | 	uint8_t			len; |
| 439 | 	uint8_t			reserved[2]; |
| 440 | 	struct regid		id; |
| 441 | 	uint16_t		vol_seq_num; |
| 442 | 	uint16_t		part_num; |
| 443 | 	uint32_t		meta_file_lbn;		/* logical block number for file entry within part_num */ |
| 444 | 	uint32_t		meta_mirror_file_lbn; |
| 445 | 	uint32_t		meta_bitmap_file_lbn; |
| 446 | 	uint32_t		alloc_unit_size;	/* allocation unit size in blocks */ |
| 447 | 	uint16_t		alignment_unit_size;	/* alignment necessary in blocks */ |
| 448 | 	uint8_t			flags; |
| 449 | 	uint8_t			reserved1[5]; |
| 450 | } __packed; |
| 451 | #define METADATA_DUPLICATED	1 |
| 452 | |
| 453 | |
| 454 | union udf_pmap { |
| 455 | 	uint8_t			data[UDF_PMAP_SIZE]; |
| 456 | 	struct part_map_1	pm1; |
| 457 | 	struct part_map_2	pm2; |
| 458 | 	struct part_map_virt	pmv; |
| 459 | 	struct part_map_spare	pms; |
| 460 | 	struct part_map_meta	pmm; |
| 461 | } __packed; |
| 462 | |
| 463 | |
| 464 | /* Sparing Map Entry [UDF 2.01/2.2.11] */ |
| 465 | struct spare_map_entry { |
| 466 | 	uint32_t		org;			/* partition relative address */ |
| 467 | 	uint32_t		map;			/* absolute disc address (!) can be in partition, but doesn't have to be */ |
| 468 | } __packed; |
| 469 | |
| 470 | |
| 471 | /* Sparing Table [UDF 2.01/2.2.11] */ |
| 472 | struct udf_sparing_table { |
| 473 | 	struct desc_tag		tag; |
| 474 | 	struct regid		id; |
| 475 | 	uint16_t		rt_l;			/* Relocation Table len */ |
| 476 | 	uint8_t			reserved[2]; |
| 477 | 	uint32_t		seq_num; |
| 478 | 	struct spare_map_entry	entries[1]; |
| 479 | } __packed; |
| 480 | |
| 481 | |
| 482 | #define UDF_NO_PREV_VAT		0xffffffff |
| 483 | /* UDF 1.50 VAT suffix [UDF 2.2.10 (UDF 1.50 spec)] */ |
| 484 | struct udf_oldvat_tail { |
| 485 | 	struct regid		id;			/* "*UDF Virtual Alloc Tbl" */ |
| 486 | 	uint32_t		prev_vat; |
| 487 | } __packed; |
| 488 | |
| 489 | |
| 490 | /* VAT table [UDF 2.0.1/2.2.10] */ |
| 491 | struct udf_vat { |
| 492 | 	uint16_t		header_len; |
| 493 | 	uint16_t		impl_use_len; |
| 494 | 	char			logvol_id[128];		/* newer version of the LVD one */ |
| 495 | 	uint32_t		prev_vat; |
| 496 | 	uint32_t		num_files; |
| 497 | 	uint32_t		num_directories; |
| 498 | 	uint16_t		min_udf_readver; |
| 499 | 	uint16_t		min_udf_writever; |
| 500 | 	uint16_t		max_udf_writever; |
| 501 | 	uint16_t		reserved; |
| 502 | 	uint8_t			data[1];		/* impl.use followed by VAT entries (uint32_t) */ |
| 503 | } __packed; |
| 504 | |
| 505 | |
| 506 | /* Space bitmap descriptor as found in the partition header descriptor */ |
| 507 | struct space_bitmap_desc { |
| 508 | 	struct desc_tag		tag;			/* TagId 264			*/ |
| 509 | 	uint32_t		num_bits;		/* number of bits		*/ |
| 510 | 	uint32_t		num_bytes;		/* bytes that contain it	*/ |
| 511 | 	uint8_t			data[1]; |
| 512 | } __packed; |
| 513 | |
| 514 | |
| 515 | /* Unalloc space entry as found in the partition header descriptor */ |
| 516 | struct space_entry_desc { |
| 517 | 	struct desc_tag		tag;			/* TagId 263			*/ |
| 518 | 	struct icb_tag		icbtag;			/* type 1			*/ |
| 519 | 	uint32_t		l_ad;			/* in bytes			*/ |
| 520 | 	uint8_t			entry[1]; |
| 521 | } __packed; |
| 522 | |
| 523 | |
| 524 | /* Partition header descriptor; in the contents_use of part_desc */ |
| 525 | struct part_hdr_desc { |
| 526 | 	struct short_ad		unalloc_space_table; |
| 527 | 	struct short_ad		unalloc_space_bitmap; |
| 528 | 	struct short_ad		part_integrity_table;	/* has to be ZERO for UDF */ |
| 529 | 	struct short_ad		freed_space_table; |
| 530 | 	struct short_ad		freed_space_bitmap; |
| 531 | 	uint8_t			reserved[88]; |
| 532 | } __packed; |
| 533 | |
| 534 | |
| 535 | /* Partition Descriptor [3/10.5] */ |
| 536 | struct part_desc { |
| 537 | 	struct desc_tag		tag; |
| 538 | 	uint32_t		seq_num;		/* MAX prevailing */ |
| 539 | 	uint16_t		flags;			/* bit 0 : if set the space is allocated */ |
| 540 | 	uint16_t		part_num;		/* KEY */ |
| 541 | 	struct regid		contents; |
| 542 | 	union { |
| 543 | 		struct part_hdr_desc	part_hdr; |
| 544 | 		uint8_t			contents_use[128]; |
| 545 | 	} _impl_use; |
| 546 | 	uint32_t		access_type;		/* R/W, WORM etc. */ |
| 547 | 	uint32_t		start_loc;		/* start of partition with given length */ |
| 548 | 	uint32_t		part_len; |
| 549 | 	struct regid		imp_id; |
| 550 | 	uint8_t			imp_use[128]; |
| 551 | 	uint8_t			reserved[156]; |
| 552 | } __packed; |
| 553 | #define pd_part_hdr _impl_use.part_hdr |
| 554 | #define UDF_PART_FLAG_ALLOCATED		1 |
| 555 | |
| 556 | |
| 557 | /* Unallocated Space Descriptor (UDF 2.01/2.2.5) */ |
| 558 | struct unalloc_sp_desc { |
| 559 | 	struct desc_tag		tag; |
| 560 | 	uint32_t		seq_num;	/* MAX prevailing */ |
| 561 | 	uint32_t		alloc_desc_num; |
| 562 | 	struct extent_ad	alloc_desc[1]; |
| 563 | } __packed; |
| 564 | |
| 565 | |
| 566 | /* Logical Volume Integrity Descriptor [3/30.10] */ |
| 567 | struct logvolhdr { |
| 568 | 	uint64_t		next_unique_id; |
| 569 | 	/* rest reserved */ |
| 570 | } __packed; |
| 571 | |
| 572 | |
| 573 | struct udf_logvol_info { |
| 574 | 	struct regid		impl_id; |
| 575 | 	uint32_t		num_files; |
| 576 | 	uint32_t		num_directories; |
| 577 | 	uint16_t		min_udf_readver; |
| 578 | 	uint16_t		min_udf_writever; |
| 579 | 	uint16_t		max_udf_writever; |
| 580 | } __packed; |
| 581 | |
| 582 | |
| 583 | struct logvol_int_desc { |
| 584 | 	struct desc_tag		tag; |
| 585 | 	struct timestamp	time; |
| 586 | 	uint32_t		integrity_type; |
| 587 | 	struct extent_ad	next_extent; |
| 588 | 	union { |
| 589 | 		struct logvolhdr logvolhdr; |
| 590 | 		int8_t		 reserved[32]; |
| 591 | 	} __packed _impl_use; |
| 592 | 	uint32_t		num_part; |
| 593 | 	uint32_t		l_iu; |
| 594 | 	uint32_t		tables[1];	/* Freespace table, Sizetable, Implementation use */ |
| 595 | } __packed; |
| 596 | #define lvint_next_unique_id _impl_use.logvolhdr.next_unique_id |
| 597 | |
| 598 | |
| 599 | /* File Set Descriptor [4/14.1] */ |
| 600 | struct fileset_desc { |
| 601 | 	struct desc_tag		tag; |
| 602 | 	struct timestamp	time; |
| 603 | 	uint16_t		ichg_lvl; |
| 604 | 	uint16_t		max_ichg_lvl; |
| 605 | 	uint32_t		charset_list; |
| 606 | 	uint32_t		max_charset_list; |
| 607 | 	uint32_t		fileset_num;			/* key! */ |
| 608 | 	uint32_t		fileset_desc_num; |
| 609 | 	struct charspec		logvol_id_charset; |
| 610 | 	char			logvol_id[128];			/* for recovery			*/ |
| 611 | 	struct charspec		fileset_charset; |
| 612 | 	char			fileset_id[32];			/* Mountpoint !!		*/ |
| 613 | 	char			copyright_file_id[32]; |
| 614 | 	char			abstract_file_id[32]; |
| 615 | 	struct long_ad		rootdir_icb;			/* to rootdir; icb->virtual ?	*/ |
| 616 | 	struct regid		domain_id; |
| 617 | 	struct long_ad		next_ex;			/* to the next fileset_desc extent */ |
| 618 | 	struct long_ad		streamdir_icb;			/* streamdir; needed?		*/ |
| 619 | 	uint8_t			reserved[32]; |
| 620 | } __packed; |
| 621 | |
| 622 | |
| 623 | /* File Identifier Descriptor [4/14.4] */ |
| 624 | struct fileid_desc { |
| 625 | 	struct desc_tag		tag; |
| 626 | 	uint16_t		file_version_num; |
| 627 | 	uint8_t			file_char; |
| 628 | 	uint8_t			l_fi;	/* Length of file identifier area */ |
| 629 | 	struct long_ad		icb; |
| 630 | 	uint16_t		l_iu;	/* Length of implementation use area */ |
| 631 | 	uint8_t			data[0]; |
| 632 | } __packed; |
| 633 | #define	UDF_FID_SIZE	38 |
| 634 | #define	UDF_FILE_CHAR_VIS	(1 << 0) /* Invisible */ |
| 635 | #define	UDF_FILE_CHAR_DIR	(1 << 1) /* Directory */ |
| 636 | #define	UDF_FILE_CHAR_DEL	(1 << 2) /* Deleted */ |
| 637 | #define	UDF_FILE_CHAR_PAR	(1 << 3) /* Parent Directory */ |
| 638 | #define	UDF_FILE_CHAR_META	(1 << 4) /* Stream metadata */ |
| 639 | |
| 640 | |
| 641 | /* Extended attributes [4/14.10.1] */ |
| 642 | struct extattrhdr_desc { |
| 643 | 	struct desc_tag		tag; |
| 644 | 	uint32_t		impl_attr_loc;	/* offsets within this descriptor */ |
| 645 | 	uint32_t		appl_attr_loc;	/* ditto */ |
| 646 | } __packed; |
| 647 | #define UDF_IMPL_ATTR_LOC_NOT_PRESENT 0xffffffff |
| 648 | #define UDF_APPL_ATTR_LOC_NOT_PRESENT 0xffffffff |
| 649 | |
| 650 | |
| 651 | /* Extended attribute entry [4/48.10.2] */ |
| 652 | struct extattr_entry { |
| 653 | 	uint32_t		type; |
| 654 | 	uint8_t			subtype; |
| 655 | 	uint8_t			reserved[3]; |
| 656 | 	uint32_t		a_l; |
| 657 | } __packed; |
| 658 | |
| 659 | |
| 660 | /* Extended attribute entry; type 2048 [4/48.10.8] */ |
| 661 | struct impl_extattr_entry { |
| 662 | 	struct extattr_entry hdr; |
| 663 | 	uint32_t		iu_l; |
| 664 | 	struct regid		imp_id; |
| 665 | 	uint8_t			data[1]; |
| 666 | } __packed; |
| 667 | |
| 668 | |
| 669 | /* Extended attribute entry; type 65 536 [4/48.10.9] */ |
| 670 | struct appl_extattr_entry { |
| 671 | 	struct extattr_entry hdr; |
| 672 | 	uint32_t		au_l; |
| 673 | 	struct regid		appl_id; |
| 674 | 	uint8_t			data[1]; |
| 675 | } __packed; |
| 676 | |
| 677 | |
| 678 | /* File Times attribute entry; type 5 or type 6 [4/48.10.5], [4/48.10.6] */ |
| 679 | struct filetimes_extattr_entry { |
| 680 | 	struct extattr_entry hdr; |
| 681 | 	uint32_t		d_l;		/* length of times[] data following */ |
| 682 | 	uint32_t		existence;	/* bitmask */ |
| 683 | 	struct timestamp	times[1];	/* in order of ascending bits */ |
| 684 | } __packed; |
| 685 | #define UDF_FILETIMES_ATTR_NO	5 |
| 686 | #define UDF_FILETIMES_FILE_CREATION	1 |
| 687 | #define UDF_FILETIMES_FILE_DELETION	4 |
| 688 | #define UDF_FILETIMES_FILE_EFFECTIVE	8 |
| 689 | #define UDF_FILETIMES_FILE_BACKUPED	16 |
| 690 | #define UDF_FILETIMES_ATTR_SIZE(no)	(20 + (no)*sizeof(struct timestamp)) |
| 691 | |
| 692 | |
| 693 | /* Device Specification Extended Attribute [4/4.10.7] */ |
| 694 | struct device_extattr_entry { |
| 695 | 	struct extattr_entry	hdr; |
| 696 | 	uint32_t		iu_l;		/* length of implementation use */ |
| 697 | 	uint32_t		major; |
| 698 | 	uint32_t		minor; |
| 699 | 	uint8_t			data[1];	/* UDF: if nonzero length, contain developer ID regid */ |
| 700 | } __packed; |
| 701 | #define UDF_DEVICESPEC_ATTR_NO	12 |
| 702 | |
| 703 | |
| 704 | /* VAT LV extension Extended Attribute [UDF 3.3.4.5.1.3] 1.50 errata */ |
| 705 | struct vatlvext_extattr_entry { |
| 706 | 	uint64_t		unique_id_chk;	/* needs to be copy of ICB's */ |
| 707 | 	uint32_t		num_files; |
| 708 | 	uint32_t		num_directories; |
| 709 | 	char			logvol_id[128];	/* replaces logvol name */ |
| 710 | } __packed; |
| 711 | |
| 712 | |
| 713 | /* File Entry [4/14.9] */ |
| 714 | struct file_entry { |
| 715 | 	struct desc_tag		tag; |
| 716 | 	struct icb_tag		icbtag; |
| 717 | 	uint32_t		uid; |
| 718 | 	uint32_t		gid; |
| 719 | 	uint32_t		perm; |
| 720 | 	uint16_t		link_cnt; |
| 721 | 	uint8_t			rec_format; |
| 722 | 	uint8_t			rec_disp_attr; |
| 723 | 	uint32_t		rec_len; |
| 724 | 	uint64_t		inf_len; |
| 725 | 	uint64_t		logblks_rec; |
| 726 | 	struct timestamp	atime; |
| 727 | 	struct timestamp	mtime; |
| 728 | 	struct timestamp	attrtime; |
| 729 | 	uint32_t		ckpoint; |
| 730 | 	struct long_ad		ex_attr_icb; |
| 731 | 	struct regid		imp_id; |
| 732 | 	uint64_t		unique_id; |
| 733 | 	uint32_t		l_ea;	/* Length of extended attribute area */ |
| 734 | 	uint32_t		l_ad;	/* Length of allocation descriptors */ |
| 735 | 	uint8_t			data[1]; |
| 736 | } __packed; |
| 737 | #define	UDF_FENTRY_SIZE	176 |
| 738 | #define	UDF_FENTRY_PERM_USER_MASK	0x07 |
| 739 | #define	UDF_FENTRY_PERM_GRP_MASK	0xE0 |
| 740 | #define	UDF_FENTRY_PERM_OWNER_MASK	0x1C00 |
| 741 | |
| 742 | |
| 743 | /* Extended File Entry [4/48.17] */ |
| 744 | struct extfile_entry { |
| 745 | 	struct desc_tag		tag; |
| 746 | 	struct icb_tag		icbtag; |
| 747 | 	uint32_t		uid; |
| 748 | 	uint32_t		gid; |
| 749 | 	uint32_t		perm; |
| 750 | 	uint16_t		link_cnt; |
| 751 | 	uint8_t			rec_format; |
| 752 | 	uint8_t			rec_disp_attr; |
| 753 | 	uint32_t		rec_len; |
| 754 | 	uint64_t		inf_len; |
| 755 | 	uint64_t		obj_size; |
| 756 | 	uint64_t		logblks_rec; |
| 757 | 	struct timestamp	atime; |
| 758 | 	struct timestamp	mtime; |
| 759 | 	struct timestamp	ctime; |
| 760 | 	struct timestamp	attrtime; |
| 761 | 	uint32_t		ckpoint; |
| 762 | 	uint32_t		reserved1; |
| 763 | 	struct long_ad		ex_attr_icb; |
| 764 | 	struct long_ad		streamdir_icb; |
| 765 | 	struct regid		imp_id; |
| 766 | 	uint64_t		unique_id; |
| 767 | 	uint32_t		l_ea;	/* Length of extended attribute area */ |
| 768 | 	uint32_t		l_ad;	/* Length of allocation descriptors */ |
| 769 | 	uint8_t			data[1]; |
| 770 | } __packed; |
| 771 | #define	UDF_EXTFENTRY_SIZE	216 |
| 772 | |
| 773 | |
| 774 | /* Indirect entry [ecma 48.7] */ |
| 775 | struct indirect_entry { |
| 776 | 	struct desc_tag		tag; |
| 777 | 	struct icb_tag		icbtag; |
| 778 | 	struct long_ad		indirect_icb; |
| 779 | } __packed; |
| 780 | |
| 781 | |
| 782 | /* Allocation extent descriptor [ecma 48.5] */ |
| 783 | struct alloc_ext_entry { |
| 784 | 	struct desc_tag		tag; |
| 785 | 	uint32_t		prev_entry; |
| 786 | 	uint32_t		l_ad; |
| 787 | 	uint8_t			data[1]; |
| 788 | } __packed; |
| 789 | |
| 790 | |
| 791 | union dscrptr { |
| 792 | 	struct desc_tag		 tag; |
| 793 | 	struct anchor_vdp	 avdp; |
| 794 | 	struct vol_desc_ptr	 vdp; |
| 795 | 	struct pri_vol_desc	 pvd; |
| 796 | 	struct logvol_desc	 lvd; |
| 797 | 	struct unalloc_sp_desc	 usd; |
| 798 | 	struct logvol_int_desc	 lvid; |
| 799 | 	struct impvol_desc	 ivd; |
| 800 | 	struct part_desc	 pd; |
| 801 | 	struct fileset_desc	 fsd; |
| 802 | 	struct fileid_desc	 fid; |
| 803 | 	struct file_entry	 fe; |
| 804 | 	struct extfile_entry	 efe; |
| 805 | 	struct extattrhdr_desc	 eahd; |
| 806 | 	struct indirect_entry	 inde; |
| 807 | 	struct alloc_ext_entry	 aee; |
| 808 | 	struct udf_sparing_table spt; |
| 809 | 	struct space_bitmap_desc sbd; |
| 810 | 	struct space_entry_desc	 sed; |
| 811 | } __packed; |
| 812 | |
| 813 | /* Useful defines */ |
| 814 | |
| 815 | #define	GETICB(ad_type, fentry, offset)	\ |
| 816 | 	(struct ad_type *)&fentry->data[offset] |
| 817 | |
| 818 | #define	GETICBLEN(ad_type, icb)	letoh32(((struct ad_type *)(icb))->len) |
| 819 | |
| 820 | #endif /* !_FS_UDF_ECMA167_UDF_H_ */ |