xref: /minix/sbin/newfs_udf/udf_create.c (revision 0a6a1f1d)
1 /* $NetBSD: udf_create.c,v 1.25 2015/06/16 23:18:55 christos Exp $ */
2 
3 /*
4  * Copyright (c) 2006, 2008 Reinoud Zandijk
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  *
27  */
28 #if HAVE_NBTOOL_CONFIG_H
29 #include "nbtool_config.h"
30 #endif
31 
32 #include <sys/cdefs.h>
33 __RCSID("$NetBSD: udf_create.c,v 1.25 2015/06/16 23:18:55 christos Exp $");
34 
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <stddef.h>
38 #include <string.h>
39 #include <errno.h>
40 #include <time.h>
41 #include <assert.h>
42 #include <err.h>
43 #include <sys/types.h>
44 #include <sys/param.h>
45 #include "unicode.h"
46 #include "udf_create.h"
47 
48 
49 #if 0
50 # ifndef DEBUG
51 #   define DEBUG
52 #  endif
53 #endif
54 
55 /*
56  * NOTE that there is some overlap between this code and the udf kernel fs.
57  * This is intentially though it might better be factored out one day.
58  */
59 
60 void
61 udf_init_create_context(void)
62 {
63 	/* clear */
64 	memset(&context, 0, sizeof(struct udf_create_context));
65 
66 	/* fill with defaults currently known */
67 	context.dscrver = 3;
68 	context.min_udf = 0x0102;
69 	context.max_udf = 0x0260;
70 	context.serialnum = 1;		/* default */
71 
72 	context.gmtoff  = 0;
73 	context.sector_size = 512;	/* minimum for UDF */
74 
75 	context.logvol_name  = NULL;
76 	context.primary_name = NULL;
77 	context.volset_name  = NULL;
78 	context.fileset_name = NULL;
79 
80 	/* most basic identification */
81 	context.app_name	 = "*NetBSD";
82 	context.app_version_main = 0;
83 	context.app_version_sub  = 0;
84 	context.impl_name        = "*NetBSD";
85 
86 	context.vds_seq = 0;		/* first one starts with zero */
87 
88 	/* Minimum value of 16 : UDF 3.2.1.1, 3.3.3.4. */
89 	context.unique_id       = 0x10;
90 
91 	context.num_files       = 0;
92 	context.num_directories = 0;
93 
94 	context.data_part          = 0;
95 	context.metadata_part      = 0;
96 	context.metadata_alloc_pos = 0;
97 	context.data_alloc_pos     = 0;
98 }
99 
100 
101 /* version can be specified as 0xabc or a.bc */
102 static int
103 parse_udfversion(const char *pos, uint32_t *version) {
104 	int hex = 0;
105 	char c1, c2, c3, c4;
106 
107 	*version = 0;
108 	if (*pos == '0') {
109 		pos++;
110 		/* expect hex format */
111 		hex = 1;
112 		if (*pos++ != 'x')
113 			return 1;
114 	}
115 
116 	c1 = *pos++;
117 	if (c1 < '0' || c1 > '9')
118 		return 1;
119 	c1 -= '0';
120 
121 	c2 = *pos++;
122 	if (!hex) {
123 		if (c2 != '.')
124 			return 1;
125 		c2 = *pos++;
126 	}
127 	if (c2 < '0' || c2 > '9')
128 		return 1;
129 	c2 -= '0';
130 
131 	c3 = *pos++;
132 	if (c3 < '0' || c3 > '9')
133 		return 1;
134 	c3 -= '0';
135 
136 	c4 = *pos++;
137 	if (c4 != 0)
138 		return 1;
139 
140 	*version = c1 * 0x100 + c2 * 0x10 + c3;
141 	return 0;
142 }
143 
144 
145 /* parse a given string for an udf version */
146 int
147 a_udf_version(const char *s, const char *id_type)
148 {
149 	uint32_t version;
150 
151 	if (parse_udfversion(s, &version))
152 		errx(1, "unknown %s id %s; specify as hex or float", id_type, s);
153 	return version;
154 }
155 
156 
157 static uint32_t
158 udf_space_bitmap_len(uint32_t part_size)
159 {
160 	return  sizeof(struct space_bitmap_desc)-1 +
161 		part_size/8;
162 }
163 
164 
165 static uint32_t
166 udf_bytes_to_sectors(uint64_t bytes)
167 {
168 	uint32_t sector_size = layout.sector_size;
169 	return (bytes + sector_size -1) / sector_size;
170 }
171 
172 
173 int
174 udf_calculate_disc_layout(int format_flags, int min_udf,
175 	uint32_t wrtrack_skew,
176 	uint32_t first_lba, uint32_t last_lba,
177 	uint32_t sector_size, uint32_t blockingnr,
178 	uint32_t sparable_blocks, float meta_fract)
179 {
180 	uint64_t kbsize, bytes;
181 	uint32_t sparable_blockingnr;
182 	uint32_t align_blockingnr;
183 	uint32_t pos, mpos;
184 
185 	/* clear */
186 	memset(&layout, 0, sizeof(layout));
187 
188 	/* fill with parameters */
189 	layout.wrtrack_skew    = wrtrack_skew;
190 	layout.first_lba       = first_lba;
191 	layout.last_lba        = last_lba;
192 	layout.sector_size     = sector_size;
193 	layout.blockingnr      = blockingnr;
194 	layout.sparable_blocks = sparable_blocks;
195 
196 	/* start disc layouting */
197 
198 	/*
199 	 * location of iso9660 vrs is defined as first sector AFTER 32kb,
200 	 * minimum `sector size' 2048
201 	 */
202 	layout.iso9660_vrs = ((32*1024 + sector_size - 1) / sector_size)
203 		+ first_lba;
204 
205 	/* anchor starts at specified offset in sectors */
206 	layout.anchors[0] = first_lba + 256;
207 	if (format_flags & FORMAT_TRACK512)
208 		layout.anchors[0] = first_lba + 512;
209 	layout.anchors[1] = last_lba - 256;
210 	layout.anchors[2] = last_lba;
211 
212 	/* update workable space */
213 	first_lba = layout.anchors[0] + blockingnr;
214 	last_lba  = layout.anchors[1] - 1;
215 
216 	/* XXX rest of anchor packet can be added to unallocated space descr */
217 
218 	/* reserve space for VRS and VRS copy and associated tables */
219 	layout.vds_size = MAX(16, blockingnr);     /* UDF 2.2.3.1+2 */
220 	layout.vds1 = first_lba;
221 	first_lba += layout.vds_size;              /* next packet */
222 
223 	if (format_flags & FORMAT_SEQUENTIAL) {
224 		/* for sequential, append them ASAP */
225 		layout.vds2 = first_lba;
226 		first_lba += layout.vds_size;
227 	} else {
228 		layout.vds2 = layout.anchors[1] - layout.vds_size;
229 		last_lba = layout.vds2 - 1;	/* XXX -1 ?? */
230 	}
231 
232 	/* reserve space for logvol integrity sequence */
233 	layout.lvis_size = MAX(8192/sector_size, 2 * blockingnr);
234 	if (format_flags & FORMAT_VAT)
235 		layout.lvis_size = 2;
236 	if (format_flags & FORMAT_WORM)
237 		layout.lvis_size = 64 * blockingnr;
238 
239 	/* TODO skip bad blocks in LVID sequence; for now use f.e. */
240 //first_lba+=128;
241 	layout.lvis = first_lba;
242 	first_lba += layout.lvis_size;
243 
244 	/* initial guess of UDF partition size */
245 	layout.part_start_lba = first_lba;
246 	layout.part_size_lba = last_lba - layout.part_start_lba;
247 
248 	/* all non sequential media needs an unallocated space bitmap */
249 	layout.alloc_bitmap_dscr_size = 0;
250 	if ((format_flags & (FORMAT_SEQUENTIAL | FORMAT_READONLY)) == 0) {
251 		bytes = udf_space_bitmap_len(layout.part_size_lba);
252 		layout.alloc_bitmap_dscr_size = udf_bytes_to_sectors(bytes);
253 
254 		/* XXX freed space map when applicable */
255 	}
256 
257 	/*
258 	 * Note that for (bug) compatibility with version UDF 2.00 (fixed in
259 	 * 2.01 and higher) the blocking size needs to be 32 sectors otherwise
260 	 * the drive's blockingnr.
261 	 */
262 
263 	sparable_blockingnr = blockingnr;
264 	if (min_udf <= 0x200)
265 		sparable_blockingnr = 32;
266 
267 	align_blockingnr = blockingnr;
268 	if (format_flags & (FORMAT_SPARABLE | FORMAT_META))
269 		align_blockingnr = sparable_blockingnr;
270 
271 	layout.align_blockingnr    = align_blockingnr;
272 	layout.sparable_blockingnr = sparable_blockingnr;
273 
274 	/*
275 	 * Align partition LBA space to blocking granularity. Not strickly
276 	 * nessisary for non sparables but safer for the VRS data since it is
277 	 * not updated sporadically
278 	 */
279 
280 	if ((format_flags & (FORMAT_SEQUENTIAL | FORMAT_READONLY)) == 0) {
281 #ifdef DEBUG
282 		printf("Lost %d slack sectors at start\n", UDF_ROUNDUP(
283 			first_lba - wrtrack_skew, align_blockingnr) -
284 				(first_lba - wrtrack_skew));
285 		printf("Lost %d slack sectors at end\n",
286 			(first_lba - wrtrack_skew) - UDF_ROUNDDOWN(
287 				first_lba - wrtrack_skew, align_blockingnr));
288 #endif
289 
290 		first_lba = UDF_ROUNDUP( first_lba - wrtrack_skew,
291 				align_blockingnr);
292 		last_lba  = UDF_ROUNDDOWN(last_lba - wrtrack_skew,
293 				align_blockingnr);
294 	}
295 
296 	if ((format_flags & FORMAT_SPARABLE) == 0)
297 		layout.sparable_blocks = 0;
298 
299 	if (format_flags & FORMAT_SPARABLE) {
300 		layout.sparable_area_size =
301 			layout.sparable_blocks * sparable_blockingnr;
302 
303 		/* a sparing table descriptor is a whole blockingnr sectors */
304 		layout.sparing_table_dscr_lbas = sparable_blockingnr;
305 
306 		/* place the descriptors at the start and end of the area */
307 		layout.spt_1 = first_lba;
308 		first_lba += layout.sparing_table_dscr_lbas;
309 
310 		layout.spt_2 = last_lba - layout.sparing_table_dscr_lbas;
311 		last_lba -= layout.sparing_table_dscr_lbas;
312 
313 		/* allocate sparable section */
314 		layout.sparable_area = first_lba;
315 		first_lba += layout.sparable_area_size;
316 	}
317 
318 	/* update guess of UDF partition size */
319 	layout.part_start_lba = first_lba;
320 	layout.part_size_lba = last_lba - layout.part_start_lba;
321 
322 	/* determine partition selection for data and metadata */
323 	context.data_part     = 0;
324 	context.metadata_part = context.data_part;
325 	if ((format_flags & FORMAT_VAT) || (format_flags & FORMAT_META))
326 		context.metadata_part = context.data_part + 1;
327 
328 	/*
329 	 * Pick fixed logical space sector numbers for main FSD, rootdir and
330 	 * unallocated space. The reason for this pre-allocation is that they
331 	 * are referenced in the volume descriptor sequence and hence can't be
332 	 * allocated later.
333 	 */
334 	pos = 0;
335 	layout.unalloc_space = pos;
336 	pos += layout.alloc_bitmap_dscr_size;
337 
338 	/* claim metadata descriptors and partition space [UDF 2.2.10] */
339 	if (format_flags & FORMAT_META) {
340 		/* note: all in backing partition space */
341 		layout.meta_file   = pos++;
342 		layout.meta_bitmap = pos++;;
343 		layout.meta_mirror = layout.part_size_lba-1;
344 		layout.meta_alignment  = MAX(blockingnr, sparable_blockingnr);
345 		layout.meta_blockingnr = MAX(layout.meta_alignment, 32);
346 
347 		/* calculate our partition length and store in sectors */
348 		layout.meta_part_size_lba = layout.part_size_lba * meta_fract;
349 		layout.meta_part_size_lba = MAX(layout.meta_part_size_lba, 32);
350 		layout.meta_part_size_lba =
351 			UDF_ROUNDDOWN(layout.meta_part_size_lba, layout.meta_blockingnr);
352 
353 		/* calculate positions */
354 		bytes = udf_space_bitmap_len(layout.meta_part_size_lba);
355 		layout.meta_bitmap_dscr_size = udf_bytes_to_sectors(bytes);
356 
357 		layout.meta_bitmap_space = pos;
358 		pos += layout.meta_bitmap_dscr_size;
359 
360 		layout.meta_part_start_lba  = UDF_ROUNDUP(pos, layout.meta_alignment);
361 	}
362 
363 	mpos = (context.metadata_part == context.data_part) ? pos : 0;
364 	layout.fsd           = mpos;	mpos += 1;
365 	layout.rootdir       = mpos;	mpos += 1;
366 	layout.vat           = mpos;	mpos += 1;	/* if present */
367 
368 #if 0
369 	printf("Summary so far\n");
370 	printf("\tiso9660_vrs\t\t%d\n", layout.iso9660_vrs);
371 	printf("\tanchor0\t\t\t%d\n", layout.anchors[0]);
372 	printf("\tanchor1\t\t\t%d\n", layout.anchors[1]);
373 	printf("\tanchor2\t\t\t%d\n", layout.anchors[2]);
374 	printf("\tvds_size\t\t%d\n", layout.vds_size);
375 	printf("\tvds1\t\t\t%d\n", layout.vds1);
376 	printf("\tvds2\t\t\t%d\n", layout.vds2);
377 	printf("\tlvis_size\t\t%d\n", layout.lvis_size);
378 	printf("\tlvis\t\t\t%d\n", layout.lvis);
379 	if (format_flags & FORMAT_SPARABLE) {
380 		printf("\tsparable size\t\t%d\n", layout.sparable_area_size);
381 		printf("\tsparable\t\t%d\n", layout.sparable_area);
382 	}
383 	printf("\tpartition start lba\t%d\n", layout.part_start_lba);
384 	printf("\tpartition size\t\t%d KiB, %d MiB\n",
385 		(layout.part_size_lba * sector_size) / 1024,
386 		(layout.part_size_lba * sector_size) / (1024*1024));
387 	if ((format_flags & FORMAT_SEQUENTIAL) == 0) {
388 		printf("\tpart bitmap start\t%d\n",   layout.unalloc_space);
389 		printf("\t\tfor %d lba\n", layout.alloc_bitmap_dscr_size);
390 	}
391 	if (format_flags & FORMAT_META) {
392 		printf("\tmeta blockingnr\t\t%d\n", layout.meta_blockingnr);
393 		printf("\tmeta alignment\t\t%d\n",  layout.meta_alignment);
394 		printf("\tmeta size\t\t%d KiB, %d MiB\n",
395 			(layout.meta_part_size_lba * sector_size) / 1024,
396 			(layout.meta_part_size_lba * sector_size) / (1024*1024));
397 		printf("\tmeta file\t\t%d\n", layout.meta_file);
398 		printf("\tmeta mirror\t\t%d\n", layout.meta_mirror);
399 		printf("\tmeta bitmap\t\t%d\n", layout.meta_bitmap);
400 		printf("\tmeta bitmap start\t%d\n", layout.meta_bitmap_space);
401 		printf("\t\tfor %d lba\n", layout.meta_bitmap_dscr_size);
402 		printf("\tmeta space start\t%d\n",  layout.meta_part_start_lba);
403 		printf("\t\tfor %d lba\n", layout.meta_part_size_lba);
404 	}
405 	printf("\n");
406 #endif
407 
408 	kbsize = (uint64_t) last_lba * sector_size;
409 	printf("Total space on this medium approx. "
410 			"%"PRIu64" KiB, %"PRIu64" MiB\n",
411 			kbsize/1024, kbsize/(1024*1024));
412 	kbsize = (uint64_t)(layout.part_size_lba - layout.alloc_bitmap_dscr_size
413 		- layout.meta_bitmap_dscr_size) * sector_size;
414 	printf("Free space on this volume approx.  "
415 			"%"PRIu64" KiB, %"PRIu64" MiB\n\n",
416 			kbsize/1024, kbsize/(1024*1024));
417 
418 	return 0;
419 }
420 
421 
422 int
423 udf_validate_tag_sum(union dscrptr *dscr)
424 {
425 	struct desc_tag *tag = &dscr->tag;
426 	uint8_t *pos, sum, cnt;
427 
428 	/* calculate TAG header checksum */
429 	pos = (uint8_t *) tag;
430 	sum = 0;
431 
432 	for(cnt = 0; cnt < 16; cnt++) {
433 		if (cnt != 4) sum += *pos;
434 		pos++;
435 	};
436 	tag->cksum = sum;	/* 8 bit */
437 
438 	return 0;
439 }
440 
441 
442 /* assumes sector number of descriptor to be allready present */
443 int
444 udf_validate_tag_and_crc_sums(union dscrptr *dscr)
445 {
446 	struct desc_tag *tag = &dscr->tag;
447 	uint16_t crc;
448 
449 	/* check payload CRC if applicable */
450 	if (udf_rw16(tag->desc_crc_len) > 0) {
451 		crc = udf_cksum(((uint8_t *) tag) + UDF_DESC_TAG_LENGTH,
452 			udf_rw16(tag->desc_crc_len));
453 		tag->desc_crc = udf_rw16(crc);
454 	};
455 
456 	/* calculate TAG header checksum */
457 	return udf_validate_tag_sum(dscr);
458 }
459 
460 
461 void
462 udf_inittag(struct desc_tag *tag, int tagid, uint32_t loc)
463 {
464 	tag->id 		= udf_rw16(tagid);
465 	tag->descriptor_ver	= udf_rw16(context.dscrver);
466 	tag->cksum		= 0;
467 	tag->reserved		= 0;
468 	tag->serial_num		= udf_rw16(context.serialnum);
469 	tag->tag_loc            = udf_rw32(loc);
470 }
471 
472 
473 int
474 udf_create_anchor(int num)
475 {
476 	struct anchor_vdp *avdp;
477 	uint32_t vds_extent_len = layout.vds_size * context.sector_size;
478 
479 	if ((avdp = calloc(1, context.sector_size)) == NULL)
480 		return ENOMEM;
481 
482 	udf_inittag(&avdp->tag, TAGID_ANCHOR, layout.anchors[num]);
483 
484 	avdp->main_vds_ex.loc = udf_rw32(layout.vds1);
485 	avdp->main_vds_ex.len = udf_rw32(vds_extent_len);
486 
487 	avdp->reserve_vds_ex.loc = udf_rw32(layout.vds2);
488 	avdp->reserve_vds_ex.len = udf_rw32(vds_extent_len);
489 
490 	/* CRC length for an anchor is 512 - tag length; defined in Ecma 167 */
491 	avdp->tag.desc_crc_len = udf_rw16(512-UDF_DESC_TAG_LENGTH);
492 
493 	context.anchors[num] = avdp;
494 	return 0;
495 }
496 
497 
498 void
499 udf_create_terminator(union dscrptr *dscr, uint32_t loc)
500 {
501 	memset(dscr, 0, context.sector_size);
502 	udf_inittag(&dscr->tag, TAGID_TERM, loc);
503 
504 	/* CRC length for an anchor is 512 - tag length; defined in Ecma 167 */
505 	dscr->tag.desc_crc_len = udf_rw16(512-UDF_DESC_TAG_LENGTH);
506 }
507 
508 
509 void
510 udf_osta_charset(struct charspec *charspec)
511 {
512 	memset(charspec, 0, sizeof(*charspec));
513 	charspec->type = 0;
514 	strcpy((char *) charspec->inf, "OSTA Compressed Unicode");
515 }
516 
517 
518 void
519 udf_encode_osta_id(char *osta_id, uint16_t len, char *text)
520 {
521 	uint16_t  u16_name[1024];
522 	uint8_t  *pos;
523 	uint16_t *pos16;
524 
525 	memset(osta_id, 0, len);
526 	if (!text || (strlen(text) == 0)) return;
527 
528 	memset(u16_name, 0, sizeof(uint16_t) * 1023);
529 
530 	/* convert ascii to 16 bits unicode */
531 	pos   = (uint8_t *) text;
532 	pos16 = u16_name;
533 	while (*pos) {
534 		*pos16 = *pos;
535 		pos++; pos16++;
536 	};
537 	*pos16 = 0;
538 
539 	udf_CompressUnicode(len, 8, (unicode_t *) u16_name, (byte *) osta_id);
540 
541 	/* Ecma 167/7.2.13 states that length is recorded in the last byte */
542 	osta_id[len-1] = strlen(text)+1;
543 }
544 
545 
546 /* first call udf_set_regid and then the suffix */
547 void
548 udf_set_regid(struct regid *regid, char const *name)
549 {
550 	memset(regid, 0, sizeof(*regid));
551 	regid->flags    = 0;		/* not dirty and not protected */
552 	strcpy((char *) regid->id, name);
553 }
554 
555 
556 void
557 udf_add_domain_regid(struct regid *regid)
558 {
559 	uint16_t *ver;
560 
561 	ver  = (uint16_t *) regid->id_suffix;
562 	*ver = udf_rw16(context.min_udf);
563 }
564 
565 
566 void
567 udf_add_udf_regid(struct regid *regid)
568 {
569 	uint16_t *ver;
570 
571 	ver  = (uint16_t *) regid->id_suffix;
572 	*ver = udf_rw16(context.min_udf);
573 
574 	regid->id_suffix[2] = 4;	/* unix */
575 	regid->id_suffix[3] = 8;	/* NetBSD */
576 }
577 
578 
579 void
580 udf_add_impl_regid(struct regid *regid)
581 {
582 	regid->id_suffix[0] = 4;	/* unix */
583 	regid->id_suffix[1] = 8;	/* NetBSD */
584 }
585 
586 
587 void
588 udf_add_app_regid(struct regid *regid)
589 {
590 	regid->id_suffix[0] = context.app_version_main;
591 	regid->id_suffix[1] = context.app_version_sub;
592 }
593 
594 
595 /*
596  * Fill in timestamp structure based on clock_gettime(). Time is reported back
597  * as a time_t accompanied with a nano second field.
598  *
599  * The husec, usec and csec could be relaxed in type.
600  */
601 static void
602 udf_timespec_to_timestamp(struct timespec *timespec, struct timestamp *timestamp)
603 {
604 	struct tm tm;
605 	uint64_t husec, usec, csec;
606 
607 	memset(timestamp, 0, sizeof(*timestamp));
608 	gmtime_r(&timespec->tv_sec, &tm);
609 
610 	/*
611 	 * Time type and time zone : see ECMA 1/7.3, UDF 2., 2.1.4.1, 3.1.1.
612 	 *
613 	 * Lower 12 bits are two complement signed timezone offset if bit 12
614 	 * (method 1) is clear. Otherwise if bit 12 is set, specify timezone
615 	 * offset to -2047 i.e. unsigned `zero'
616 	 */
617 
618 	/* set method 1 for CUT/GMT */
619 	timestamp->type_tz	= udf_rw16((1<<12) + 0);
620 	timestamp->year		= udf_rw16(tm.tm_year + 1900);
621 	timestamp->month	= tm.tm_mon + 1;	/* `tm' uses 0..11 for months */
622 	timestamp->day		= tm.tm_mday;
623 	timestamp->hour		= tm.tm_hour;
624 	timestamp->minute	= tm.tm_min;
625 	timestamp->second	= tm.tm_sec;
626 
627 	usec   = (timespec->tv_nsec + 500) / 1000;	/* round */
628 	husec  =   usec / 100;
629 	usec  -=  husec * 100;				/* only 0-99 in usec  */
630 	csec   =  husec / 100;				/* only 0-99 in csec  */
631 	husec -=   csec * 100;				/* only 0-99 in husec */
632 
633 	/* in rare cases there is overflow in csec */
634 	csec  = MIN(99, csec);
635 	husec = MIN(99, husec);
636 	usec  = MIN(99, usec);
637 
638 	timestamp->centisec	= csec;
639 	timestamp->hund_usec	= husec;
640 	timestamp->usec		= usec;
641 }
642 
643 
644 void
645 udf_set_timestamp_now(struct timestamp *timestamp)
646 {
647 	struct timespec now;
648 
649 #ifdef CLOCK_REALTIME
650 	(void)clock_gettime(CLOCK_REALTIME, &now);
651 #else
652 	struct timeval time_of_day;
653 
654 	(void)gettimeofday(&time_of_day, NULL);
655 	now.tv_sec = time_of_day.tv_sec;
656 	now.tv_nsec = time_of_day.tv_usec * 1000;
657 #endif
658 	udf_timespec_to_timestamp(&now, timestamp);
659 }
660 
661 
662 /* some code copied from sys/fs/udf */
663 
664 static void
665 udf_set_timestamp(struct timestamp *timestamp, time_t value)
666 {
667 	struct timespec t;
668 
669 	memset(&t, 0, sizeof(struct timespec));
670 	t.tv_sec  = value;
671 	t.tv_nsec = 0;
672 	udf_timespec_to_timestamp(&t, timestamp);
673 }
674 
675 
676 static uint32_t
677 unix_mode_to_udf_perm(mode_t mode)
678 {
679 	uint32_t perm;
680 
681 	perm  = ((mode & S_IRWXO)     );
682 	perm |= ((mode & S_IRWXG) << 2);
683 	perm |= ((mode & S_IRWXU) << 4);
684 	perm |= ((mode & S_IWOTH) << 3);
685 	perm |= ((mode & S_IWGRP) << 5);
686 	perm |= ((mode & S_IWUSR) << 7);
687 
688 	return perm;
689 }
690 
691 /* end of copied code */
692 
693 
694 int
695 udf_create_primaryd(void)
696 {
697 	struct pri_vol_desc *pri;
698 	uint16_t crclen;
699 
700 	pri = calloc(1, context.sector_size);
701 	if (pri == NULL)
702 		return ENOMEM;
703 
704 	memset(pri, 0, context.sector_size);
705 	udf_inittag(&pri->tag, TAGID_PRI_VOL, /* loc */ 0);
706 	pri->seq_num = udf_rw32(context.vds_seq); context.vds_seq++;
707 
708 	pri->pvd_num = udf_rw32(0);		/* default serial */
709 	udf_encode_osta_id(pri->vol_id, 32, context.primary_name);
710 
711 	/* set defaults for single disc volumes as UDF prescribes */
712 	pri->vds_num      = udf_rw16(1);
713 	pri->max_vol_seq  = udf_rw16(1);
714 	pri->ichg_lvl     = udf_rw16(2);
715 	pri->max_ichg_lvl = udf_rw16(3);
716 	pri->flags        = udf_rw16(0);
717 
718 	pri->charset_list     = udf_rw32(1);	/* only CS0 */
719 	pri->max_charset_list = udf_rw32(1);	/* only CS0 */
720 
721 	udf_encode_osta_id(pri->volset_id, 128, context.volset_name);
722 	udf_osta_charset(&pri->desc_charset);
723 	udf_osta_charset(&pri->explanatory_charset);
724 
725 	udf_set_regid(&pri->app_id, context.app_name);
726 	udf_add_app_regid(&pri->app_id);
727 
728 	udf_set_regid(&pri->imp_id, context.impl_name);
729 	udf_add_impl_regid(&pri->imp_id);
730 
731 	udf_set_timestamp_now(&pri->time);
732 
733 	crclen = sizeof(struct pri_vol_desc) - UDF_DESC_TAG_LENGTH;
734 	pri->tag.desc_crc_len = udf_rw16(crclen);
735 
736 	context.primary_vol = pri;
737 
738 	return 0;
739 }
740 
741 
742 /* XXX no support for unallocated or freed space tables yet (!) */
743 int
744 udf_create_partitiond(int part_num, int part_accesstype)
745 {
746 	struct part_desc     *pd;
747 	struct part_hdr_desc *phd;
748 	uint32_t sector_size, bitmap_bytes;
749 	uint16_t crclen;
750 
751 	sector_size = context.sector_size;
752 	bitmap_bytes = layout.alloc_bitmap_dscr_size * sector_size;
753 
754 	if (context.partitions[part_num]) {
755 		printf("Internal error: partition %d allready defined\n",
756 			part_num);
757 		return EINVAL;
758 	}
759 
760 	pd = calloc(1, context.sector_size);
761 	if (pd == NULL)
762 		return ENOMEM;
763 	phd = &pd->_impl_use.part_hdr;
764 
765 	udf_inittag(&pd->tag, TAGID_PARTITION, /* loc */ 0);
766 	pd->seq_num  = udf_rw32(context.vds_seq); context.vds_seq++;
767 
768 	pd->flags    = udf_rw16(1);		/* allocated */
769 	pd->part_num = udf_rw16(part_num);	/* only one physical partition */
770 
771 	if (context.dscrver == 2) {
772 		udf_set_regid(&pd->contents, "+NSR02");
773 	} else {
774 		udf_set_regid(&pd->contents, "+NSR03");
775 	}
776 	udf_add_app_regid(&pd->contents);
777 
778 	phd->unalloc_space_bitmap.len    = udf_rw32(bitmap_bytes);
779 	phd->unalloc_space_bitmap.lb_num = udf_rw32(layout.unalloc_space);
780 
781 	if (layout.freed_space) {
782 		phd->freed_space_bitmap.len    = udf_rw32(bitmap_bytes);
783 		phd->freed_space_bitmap.lb_num = udf_rw32(layout.freed_space);
784 	}
785 
786 	pd->access_type = udf_rw32(part_accesstype);
787 	pd->start_loc   = udf_rw32(layout.part_start_lba);
788 	pd->part_len    = udf_rw32(layout.part_size_lba);
789 
790 	udf_set_regid(&pd->imp_id, context.impl_name);
791 	udf_add_impl_regid(&pd->imp_id);
792 
793 	crclen = sizeof(struct part_desc) - UDF_DESC_TAG_LENGTH;
794 	pd->tag.desc_crc_len = udf_rw16(crclen);
795 
796 	context.partitions[part_num] = pd;
797 
798 	return 0;
799 }
800 
801 
802 int
803 udf_create_unalloc_spaced(void)
804 {
805 	struct unalloc_sp_desc *usd;
806 	uint16_t crclen;
807 
808 	usd = calloc(1, context.sector_size);
809 	if (usd == NULL)
810 		return ENOMEM;
811 
812 	udf_inittag(&usd->tag, TAGID_UNALLOC_SPACE, /* loc */ 0);
813 	usd->seq_num  = udf_rw32(context.vds_seq); context.vds_seq++;
814 
815 	/* no default entries */
816 	usd->alloc_desc_num = udf_rw32(0);		/* no entries */
817 
818 	crclen  = sizeof(struct unalloc_sp_desc) - sizeof(struct extent_ad);
819 	crclen -= UDF_DESC_TAG_LENGTH;
820 	usd->tag.desc_crc_len = udf_rw16(crclen);
821 
822 	context.unallocated = usd;
823 
824 	return 0;
825 }
826 
827 
828 static int
829 udf_create_base_logical_dscr(void)
830 {
831 	struct logvol_desc *lvd;
832 	uint32_t sector_size;
833 	uint16_t crclen;
834 
835 	sector_size = context.sector_size;
836 
837 	lvd = calloc(1, sector_size);
838 	if (lvd == NULL)
839 		return ENOMEM;
840 
841 	udf_inittag(&lvd->tag, TAGID_LOGVOL, /* loc */ 0);
842 	lvd->seq_num  = udf_rw32(context.vds_seq); context.vds_seq++;
843 
844 	udf_osta_charset(&lvd->desc_charset);
845 	udf_encode_osta_id(lvd->logvol_id, 128, context.logvol_name);
846 	lvd->lb_size = udf_rw32(context.sector_size);
847 
848 	udf_set_regid(&lvd->domain_id, "*OSTA UDF Compliant");
849 	udf_add_domain_regid(&lvd->domain_id);
850 
851 	/* no partition mappings/entries yet */
852 	lvd->mt_l = udf_rw32(0);
853 	lvd->n_pm = udf_rw32(0);
854 
855 	udf_set_regid(&lvd->imp_id, context.impl_name);
856 	udf_add_impl_regid(&lvd->imp_id);
857 
858 	lvd->integrity_seq_loc.loc = udf_rw32(layout.lvis);
859 	lvd->integrity_seq_loc.len = udf_rw32(layout.lvis_size * sector_size);
860 
861 	/* just one fsd for now */
862 	lvd->lv_fsd_loc.len = udf_rw32(sector_size);
863 	lvd->lv_fsd_loc.loc.part_num = udf_rw32(context.metadata_part);
864 	lvd->lv_fsd_loc.loc.lb_num   = udf_rw32(layout.fsd);
865 
866 	crclen  = sizeof(struct logvol_desc) - 1 - UDF_DESC_TAG_LENGTH;
867 	lvd->tag.desc_crc_len = udf_rw16(crclen);
868 
869 	context.logical_vol = lvd;
870 	context.vtop_tp[UDF_VTOP_RAWPART]      = UDF_VTOP_TYPE_RAW;
871 	context.vtop_offset[UDF_VTOP_RAWPART] = 0;
872 
873 	return 0;
874 }
875 
876 
877 static void
878 udf_add_logvol_part_physical(uint16_t phys_part)
879 {
880 	struct logvol_desc *logvol = context.logical_vol;
881 	union  udf_pmap *pmap;
882 	uint8_t         *pmap_pos;
883 	uint16_t crclen;
884 	uint32_t pmap1_size, log_part;
885 
886 	log_part = udf_rw32(logvol->n_pm);
887 	pmap_pos = logvol->maps + udf_rw32(logvol->mt_l);
888 	pmap1_size = sizeof(struct part_map_1);
889 
890 	pmap = (union udf_pmap *) pmap_pos;
891 	pmap->pm1.type        = 1;
892 	pmap->pm1.len         = sizeof(struct part_map_1);
893 	pmap->pm1.vol_seq_num = udf_rw16(1);		/* no multi-volume */
894 	pmap->pm1.part_num    = udf_rw16(phys_part);
895 
896 	context.vtop       [log_part] = phys_part;
897 	context.vtop_tp    [log_part] = UDF_VTOP_TYPE_PHYS;
898 	context.vtop_offset[log_part] = layout.part_start_lba;
899 	context.part_size[log_part] = layout.part_size_lba;
900 	context.part_free[log_part] = layout.part_size_lba;
901 
902 	/* increment number of partitions and length */
903 	logvol->n_pm = udf_rw32(log_part + 1);
904 	logvol->mt_l = udf_rw32(udf_rw32(logvol->mt_l) + pmap1_size);
905 
906 	crclen = udf_rw16(logvol->tag.desc_crc_len) + pmap1_size;
907 	logvol->tag.desc_crc_len = udf_rw16(crclen);
908 }
909 
910 
911 static void
912 udf_add_logvol_part_virtual(uint16_t phys_part)
913 {
914 	union  udf_pmap *pmap;
915 	struct logvol_desc *logvol = context.logical_vol;
916 	uint8_t *pmap_pos;
917 	uint16_t crclen;
918 	uint32_t pmapv_size, log_part;
919 
920 	log_part = udf_rw32(logvol->n_pm);
921 	pmap_pos = logvol->maps + udf_rw32(logvol->mt_l);
922 	pmapv_size = sizeof(struct part_map_2);
923 
924 	pmap = (union udf_pmap *) pmap_pos;
925 	pmap->pmv.type        = 2;
926 	pmap->pmv.len         = pmapv_size;
927 
928 	udf_set_regid(&pmap->pmv.id, "*UDF Virtual Partition");
929 	udf_add_udf_regid(&pmap->pmv.id);
930 
931 	pmap->pmv.vol_seq_num = udf_rw16(1);		/* no multi-volume */
932 	pmap->pmv.part_num    = udf_rw16(phys_part);
933 
934 	context.vtop       [log_part] = phys_part;
935 	context.vtop_tp    [log_part] = UDF_VTOP_TYPE_VIRT;
936 	context.vtop_offset[log_part] = context.vtop_offset[phys_part];
937 	context.part_size[log_part] = 0xffffffff;
938 	context.part_free[log_part] = 0xffffffff;
939 
940 	/* increment number of partitions and length */
941 	logvol->n_pm = udf_rw32(log_part + 1);
942 	logvol->mt_l = udf_rw32(udf_rw32(logvol->mt_l) + pmapv_size);
943 
944 	crclen = udf_rw16(logvol->tag.desc_crc_len) + pmapv_size;
945 	logvol->tag.desc_crc_len = udf_rw16(crclen);
946 }
947 
948 
949 /* sparing table size is in bytes */
950 static void
951 udf_add_logvol_part_sparable(uint16_t phys_part)
952 {
953 	union  udf_pmap *pmap;
954 	struct logvol_desc *logvol = context.logical_vol;
955 	uint32_t *st_pos, sparable_bytes, pmaps_size;
956 	uint8_t  *pmap_pos, num;
957 	uint16_t crclen;
958 	uint32_t log_part;
959 
960 	log_part = udf_rw32(logvol->n_pm);
961 	pmap_pos = logvol->maps + udf_rw32(logvol->mt_l);
962 	pmaps_size = sizeof(struct part_map_2);
963 	sparable_bytes = layout.sparable_area_size * context.sector_size;
964 
965 	pmap = (union udf_pmap *) pmap_pos;
966 	pmap->pms.type        = 2;
967 	pmap->pms.len         = pmaps_size;
968 
969 	udf_set_regid(&pmap->pmv.id, "*UDF Sparable Partition");
970 	udf_add_udf_regid(&pmap->pmv.id);
971 
972 	pmap->pms.vol_seq_num = udf_rw16(1);		/* no multi-volume */
973 	pmap->pms.part_num    = udf_rw16(phys_part);
974 
975 	pmap->pms.packet_len  = udf_rw16(layout.sparable_blockingnr);
976 	pmap->pms.st_size     = udf_rw32(sparable_bytes);
977 
978 	/* enter spare tables  */
979 	st_pos = &pmap->pms.st_loc[0];
980 	*st_pos++ = udf_rw32(layout.spt_1);
981 	*st_pos++ = udf_rw32(layout.spt_2);
982 
983 	num = 2;
984 	if (layout.spt_2 == 0) num--;
985 	if (layout.spt_1 == 0) num--;
986 	pmap->pms.n_st = num;		/* 8 bit */
987 
988 	/* the vtop_offset needs to explicitly set since there is no phys. */
989 	context.vtop       [log_part] = phys_part;
990 	context.vtop_tp    [log_part] = UDF_VTOP_TYPE_SPARABLE;
991 	context.vtop_offset[log_part] = layout.part_start_lba;
992 	context.part_size[log_part] = layout.part_size_lba;
993 	context.part_free[log_part] = layout.part_size_lba;
994 
995 	/* increment number of partitions and length */
996 	logvol->n_pm = udf_rw32(log_part + 1);
997 	logvol->mt_l = udf_rw32(udf_rw32(logvol->mt_l) + pmaps_size);
998 
999 	crclen = udf_rw16(logvol->tag.desc_crc_len) + pmaps_size;
1000 	logvol->tag.desc_crc_len = udf_rw16(crclen);
1001 }
1002 
1003 
1004 int
1005 udf_create_sparing_tabled(void)
1006 {
1007 	struct udf_sparing_table *spt;
1008 	struct spare_map_entry   *sme;
1009 	uint32_t loc, cnt;
1010 	uint32_t crclen;	/* XXX: should be 16; need to detect overflow */
1011 
1012 	spt = calloc(context.sector_size, layout.sparing_table_dscr_lbas);
1013 	if (spt == NULL)
1014 		return ENOMEM;
1015 
1016 	/* a sparing table descriptor is a whole sparable_blockingnr sectors */
1017 	udf_inittag(&spt->tag, TAGID_SPARING_TABLE, /* loc */ 0);
1018 
1019 	udf_set_regid(&spt->id, "*UDF Sparing Table");
1020 	udf_add_udf_regid(&spt->id);
1021 
1022 	spt->rt_l    = udf_rw16(layout.sparable_blocks);
1023 	spt->seq_num = udf_rw32(0);			/* first generation */
1024 
1025 	for (cnt = 0; cnt < layout.sparable_blocks; cnt++) {
1026 		sme = &spt->entries[cnt];
1027 		loc = layout.sparable_area + cnt * layout.sparable_blockingnr;
1028 		sme->org = udf_rw32(0xffffffff);	/* open for reloc */
1029 		sme->map = udf_rw32(loc);
1030 	}
1031 
1032 	/* calculate crc len for actual size */
1033 	crclen  = sizeof(struct udf_sparing_table) - UDF_DESC_TAG_LENGTH;
1034 	crclen += (layout.sparable_blocks-1) * sizeof(struct spare_map_entry);
1035 /* XXX ensure crclen doesn't exceed UINT16_MAX ? */
1036 	spt->tag.desc_crc_len = udf_rw16((uint16_t)crclen);
1037 
1038 	context.sparing_table = spt;
1039 
1040 	return 0;
1041 }
1042 
1043 
1044 static void
1045 udf_add_logvol_part_meta(uint16_t phys_part)
1046 {
1047 	union  udf_pmap *pmap;
1048 	struct logvol_desc *logvol = context.logical_vol;
1049 	uint8_t *pmap_pos;
1050 	uint32_t pmapv_size, log_part;
1051 	uint16_t crclen;
1052 
1053 	log_part = udf_rw32(logvol->n_pm);
1054 	pmap_pos = logvol->maps + udf_rw32(logvol->mt_l);
1055 	pmapv_size = sizeof(struct part_map_2);
1056 
1057 	pmap = (union udf_pmap *) pmap_pos;
1058 	pmap->pmm.type        = 2;
1059 	pmap->pmm.len         = pmapv_size;
1060 
1061 	udf_set_regid(&pmap->pmm.id, "*UDF Metadata Partition");
1062 	udf_add_udf_regid(&pmap->pmm.id);
1063 
1064 	pmap->pmm.vol_seq_num = udf_rw16(1);		/* no multi-volume */
1065 	pmap->pmm.part_num    = udf_rw16(phys_part);
1066 
1067 	/* fill in meta data file(s) and alloc/alignment unit sizes */
1068 	pmap->pmm.meta_file_lbn        = udf_rw32(layout.meta_file);
1069 	pmap->pmm.meta_mirror_file_lbn = udf_rw32(layout.meta_mirror);
1070 	pmap->pmm.meta_bitmap_file_lbn = udf_rw32(layout.meta_bitmap);
1071 	pmap->pmm.alloc_unit_size      = udf_rw32(layout.meta_blockingnr);
1072 	pmap->pmm.alignment_unit_size  = udf_rw16(layout.meta_alignment);
1073 	pmap->pmm.flags                = 0; /* METADATA_DUPLICATED */
1074 
1075 	context.vtop       [log_part] = phys_part;
1076 	context.vtop_tp    [log_part] = UDF_VTOP_TYPE_META;
1077 	context.vtop_offset[log_part] =
1078 		context.vtop_offset[phys_part] + layout.meta_part_start_lba;
1079 	context.part_size[log_part] = layout.meta_part_size_lba;
1080 	context.part_free[log_part] = layout.meta_part_size_lba;
1081 
1082 	/* increment number of partitions and length */
1083 	logvol->n_pm = udf_rw32(log_part + 1);
1084 	logvol->mt_l = udf_rw32(udf_rw32(logvol->mt_l) + pmapv_size);
1085 
1086 	crclen = udf_rw16(logvol->tag.desc_crc_len) + pmapv_size;
1087 	logvol->tag.desc_crc_len = udf_rw16(crclen);
1088 }
1089 
1090 
1091 int
1092 udf_create_logical_dscr(int format_flags)
1093 {
1094 	int error;
1095 
1096 	if ((error = udf_create_base_logical_dscr()))
1097 		return error;
1098 
1099 	/* we pass data_part for there might be a read-only part one day */
1100 	if (format_flags & FORMAT_SPARABLE) {
1101 		/* sparable partition mapping has no physical mapping */
1102 		udf_add_logvol_part_sparable(context.data_part);
1103 	} else {
1104 		udf_add_logvol_part_physical(context.data_part);
1105 	}
1106 
1107 	if (format_flags & FORMAT_VAT) {
1108 		/* add VAT virtual mapping; reflects on datapart */
1109 		udf_add_logvol_part_virtual(context.data_part);
1110 	}
1111 	if (format_flags & FORMAT_META) {
1112 		/* add META data mapping; reflects on datapart */
1113 		udf_add_logvol_part_meta(context.data_part);
1114 	}
1115 
1116 	return 0;
1117 }
1118 
1119 
1120 int
1121 udf_create_impvold(char *field1, char *field2, char *field3)
1122 {
1123 	struct impvol_desc *ivd;
1124 	struct udf_lv_info *lvi;
1125 	uint16_t crclen;
1126 
1127 	ivd = calloc(1, context.sector_size);
1128 	if (ivd == NULL)
1129 		return ENOMEM;
1130 	lvi = &ivd->_impl_use.lv_info;
1131 
1132 	udf_inittag(&ivd->tag, TAGID_IMP_VOL, /* loc */ 0);
1133 	ivd->seq_num  = udf_rw32(context.vds_seq); context.vds_seq++;
1134 
1135 	udf_set_regid(&ivd->impl_id, "*UDF LV Info");
1136 	udf_add_udf_regid(&ivd->impl_id);
1137 
1138 	/* fill in UDF specific part */
1139 	udf_osta_charset(&lvi->lvi_charset);
1140 	udf_encode_osta_id(lvi->logvol_id, 128, context.logvol_name);
1141 
1142 	udf_encode_osta_id(lvi->lvinfo1, 36, field1);
1143 	udf_encode_osta_id(lvi->lvinfo2, 36, field2);
1144 	udf_encode_osta_id(lvi->lvinfo3, 36, field3);
1145 
1146 	udf_set_regid(&lvi->impl_id, context.impl_name);
1147 	udf_add_impl_regid(&lvi->impl_id);
1148 
1149 	crclen  = sizeof(struct impvol_desc) - UDF_DESC_TAG_LENGTH;
1150 	ivd->tag.desc_crc_len = udf_rw16(crclen);
1151 
1152 	context.implementation = ivd;
1153 
1154 	return 0;
1155 }
1156 
1157 
1158 /* XXX might need to be sanitised a bit later */
1159 void
1160 udf_update_lvintd(int type)
1161 {
1162 	struct logvol_int_desc *lvid;
1163 	struct udf_logvol_info *lvinfo;
1164 	struct logvol_desc     *logvol;
1165 	uint32_t *pos;
1166 	uint32_t cnt, l_iu, num_partmappings;
1167 	uint32_t crclen;	/* XXX: should be 16; need to detect overflow */
1168 
1169 	lvid   = context.logvol_integrity;
1170 	logvol = context.logical_vol;
1171 
1172 	assert(lvid);
1173 	assert(logvol);
1174 
1175 	lvid->integrity_type = udf_rw32(type);
1176 
1177 	num_partmappings = udf_rw32(logvol->n_pm);
1178 
1179 	udf_set_timestamp_now(&lvid->time);
1180 
1181 	lvinfo = (struct udf_logvol_info *)
1182 		(lvid->tables + num_partmappings * 2);
1183 	udf_set_regid(&lvinfo->impl_id, context.impl_name);
1184 	udf_add_impl_regid(&lvinfo->impl_id);
1185 
1186 	lvinfo->num_files          = udf_rw32(context.num_files);
1187 	lvinfo->num_directories    = udf_rw32(context.num_directories);
1188 
1189 	lvid->lvint_next_unique_id = udf_rw64(context.unique_id);
1190 
1191 	/* XXX sane enough ? */
1192 	lvinfo->min_udf_readver  = udf_rw16(context.min_udf);
1193 	lvinfo->min_udf_writever = udf_rw16(context.min_udf);
1194 	lvinfo->max_udf_writever = udf_rw16(context.max_udf);
1195 
1196 	lvid->num_part = udf_rw32(num_partmappings);
1197 
1198 	/* no impl. use needed */
1199 	l_iu = sizeof(struct udf_logvol_info);
1200 	lvid->l_iu = udf_rw32(l_iu);
1201 
1202 	pos = &lvid->tables[0];
1203 	for (cnt = 0; cnt < num_partmappings; cnt++) {
1204 		*pos++ = udf_rw32(context.part_free[cnt]);
1205 	}
1206 	for (cnt = 0; cnt < num_partmappings; cnt++) {
1207 		*pos++ = udf_rw32(context.part_size[cnt]);
1208 	}
1209 
1210 	crclen  = sizeof(struct logvol_int_desc) -4 -UDF_DESC_TAG_LENGTH + l_iu;
1211 	crclen += num_partmappings * 2 * 4;
1212 /* XXX ensure crclen doesn't exceed UINT16_MAX ? */
1213 	lvid->tag.desc_crc_len = udf_rw16(crclen);
1214 
1215 	context.logvol_info = lvinfo;
1216 }
1217 
1218 
1219 int
1220 udf_create_lvintd(int type)
1221 {
1222 	struct logvol_int_desc *lvid;
1223 
1224 	lvid = calloc(1, context.sector_size);
1225 	if (lvid == NULL)
1226 		return ENOMEM;
1227 
1228 	udf_inittag(&lvid->tag, TAGID_LOGVOL_INTEGRITY, /* loc */ 0);
1229 
1230 	context.logvol_integrity = lvid;
1231 
1232 	udf_update_lvintd(type);
1233 
1234 	return 0;
1235 }
1236 
1237 
1238 int
1239 udf_create_fsd(void)
1240 {
1241 	struct fileset_desc *fsd;
1242 	uint16_t crclen;
1243 
1244 	fsd = calloc(1, context.sector_size);
1245 	if (fsd == NULL)
1246 		return ENOMEM;
1247 
1248 	udf_inittag(&fsd->tag, TAGID_FSD, /* loc */ 0);
1249 
1250 	udf_set_timestamp_now(&fsd->time);
1251 	fsd->ichg_lvl     = udf_rw16(3);		/* UDF 2.3.2.1 */
1252 	fsd->max_ichg_lvl = udf_rw16(3);		/* UDF 2.3.2.2 */
1253 
1254 	fsd->charset_list     = udf_rw32(1);		/* only CS0 */
1255 	fsd->max_charset_list = udf_rw32(1);		/* only CS0 */
1256 
1257 	fsd->fileset_num      = udf_rw32(0);		/* only one fsd */
1258 	fsd->fileset_desc_num = udf_rw32(0);		/* origional    */
1259 
1260 	udf_osta_charset(&fsd->logvol_id_charset);
1261 	udf_encode_osta_id(fsd->logvol_id, 128, context.logvol_name);
1262 
1263 	udf_osta_charset(&fsd->fileset_charset);
1264 	udf_encode_osta_id(fsd->fileset_id, 32, context.fileset_name);
1265 
1266 	/* copyright file and abstract file names obmitted */
1267 
1268 	fsd->rootdir_icb.len	      = udf_rw32(context.sector_size);
1269 	fsd->rootdir_icb.loc.lb_num   = udf_rw32(layout.rootdir);
1270 	fsd->rootdir_icb.loc.part_num = udf_rw16(context.metadata_part);
1271 
1272 	udf_set_regid(&fsd->domain_id, "*OSTA UDF Compliant");
1273 	udf_add_domain_regid(&fsd->domain_id);
1274 
1275 	/* next_ex stays zero */
1276 	/* no system streamdirs yet */
1277 
1278 	crclen = sizeof(struct fileset_desc) - UDF_DESC_TAG_LENGTH;
1279 	fsd->tag.desc_crc_len = udf_rw16(crclen);
1280 
1281 	context.fileset_desc = fsd;
1282 
1283 	return 0;
1284 }
1285 
1286 
1287 int
1288 udf_create_space_bitmap(uint32_t dscr_size, uint32_t part_size_lba,
1289 	struct space_bitmap_desc **sbdp)
1290 {
1291 	struct space_bitmap_desc *sbd;
1292 	uint32_t cnt;
1293 	uint16_t crclen;
1294 
1295 	*sbdp = NULL;
1296 	sbd = calloc(context.sector_size, dscr_size);
1297 	if (sbd == NULL)
1298 		return ENOMEM;
1299 
1300 	udf_inittag(&sbd->tag, TAGID_SPACE_BITMAP, /* loc */ 0);
1301 
1302 	sbd->num_bits  = udf_rw32(part_size_lba);
1303 	sbd->num_bytes = udf_rw32((part_size_lba + 7)/8);
1304 
1305 	/* fill space with 0xff to indicate free */
1306 	for (cnt = 0; cnt < udf_rw32(sbd->num_bytes); cnt++)
1307 		sbd->data[cnt] = 0xff;
1308 
1309 	/* set crc to only cover the header (UDF 2.3.1.2, 2.3.8.1) */
1310 	crclen = sizeof(struct space_bitmap_desc) -1 - UDF_DESC_TAG_LENGTH;
1311 	sbd->tag.desc_crc_len = udf_rw16(crclen);
1312 
1313 	*sbdp = sbd;
1314 	return 0;
1315 }
1316 
1317 
1318 /* --------------------------------------------------------------------- */
1319 
1320 int
1321 udf_register_bad_block(uint32_t location)
1322 {
1323 	struct udf_sparing_table *spt;
1324 	struct spare_map_entry   *sme, *free_sme;
1325 	uint32_t cnt;
1326 
1327 	spt = context.sparing_table;
1328 	if (spt == NULL) {
1329 		printf("internal error: adding bad block to non sparable\n");
1330 		return EINVAL;
1331 	}
1332 
1333 	/* find us a free spare map entry */
1334 	free_sme = NULL;
1335 	for (cnt = 0; cnt < layout.sparable_blocks; cnt++) {
1336 		sme = &spt->entries[cnt];
1337 		/* if we are allready in it, bail out */
1338 		if (udf_rw32(sme->org) == location)
1339 			return 0;
1340 		if (udf_rw32(sme->org) == 0xffffffff) {
1341 			free_sme = sme;
1342 			break;
1343 		}
1344 	}
1345 	if (free_sme == NULL) {
1346 		printf("Disc relocation blocks full; disc too damanged\n");
1347 		return EINVAL;
1348 	}
1349 	free_sme->org = udf_rw32(location);
1350 
1351 	return 0;
1352 }
1353 
1354 
1355 void
1356 udf_mark_allocated(uint32_t start_lb, int partnr, uint32_t blocks)
1357 {
1358 	union dscrptr *dscr;
1359 	uint8_t *bpos;
1360 	uint32_t cnt, bit;
1361 
1362 	/* account for space used on underlying partition */
1363 	context.part_free[partnr] -= blocks;
1364 #ifdef DEBUG
1365 	printf("mark allocated : partnr %d, start_lb %d for %d blocks\n",
1366 		partnr, start_lb, blocks);
1367 #endif
1368 
1369 	switch (context.vtop_tp[partnr]) {
1370 	case UDF_VTOP_TYPE_VIRT:
1371 		/* nothing */
1372 		break;
1373 	case UDF_VTOP_TYPE_PHYS:
1374 	case UDF_VTOP_TYPE_SPARABLE:
1375 	case UDF_VTOP_TYPE_META:
1376 		if (context.part_unalloc_bits[context.vtop[partnr]] == NULL) {
1377 			context.part_free[partnr] = 0;
1378 			break;
1379 		}
1380 #ifdef DEBUG
1381 		printf("Marking %d+%d as used\n", start_lb, blocks);
1382 #endif
1383 		dscr = (union dscrptr *) (context.part_unalloc_bits[partnr]);
1384 		for (cnt = start_lb; cnt < start_lb + blocks; cnt++) {
1385 			 bpos  = &dscr->sbd.data[cnt / 8];
1386 			 bit   = cnt % 8;
1387 			*bpos &= ~(1<< bit);
1388 		}
1389 		break;
1390 	default:
1391 		printf("internal error: reality check in mapping type %d\n",
1392 			context.vtop_tp[partnr]);
1393 		exit(EXIT_FAILURE);
1394 	}
1395 }
1396 
1397 
1398 void
1399 udf_advance_uniqueid(void)
1400 {
1401 	/* Minimum value of 16 : UDF 3.2.1.1, 3.3.3.4. */
1402 	context.unique_id++;
1403 	if (context.unique_id < 0x10)
1404 		context.unique_id = 0x10;
1405 }
1406 
1407 /* --------------------------------------------------------------------- */
1408 
1409 static void
1410 unix_to_udf_name(char *result, uint8_t *result_len,
1411 	char const *name, int name_len, struct charspec *chsp)
1412 {
1413 	uint16_t   *raw_name;
1414 	uint16_t   *outchp;
1415 	const char *inchp;
1416 	const char *osta_id = "OSTA Compressed Unicode";
1417 	int         udf_chars, is_osta_typ0, bits;
1418 	size_t      cnt;
1419 
1420 	/* allocate temporary unicode-16 buffer */
1421 	raw_name = malloc(1024);
1422 	assert(raw_name);
1423 
1424 	/* convert utf8 to unicode-16 */
1425 	*raw_name = 0;
1426 	inchp  = name;
1427 	outchp = raw_name;
1428 	bits = 8;
1429 	for (cnt = name_len, udf_chars = 0; cnt;) {
1430 		*outchp = wget_utf8(&inchp, &cnt);
1431 		if (*outchp > 0xff)
1432 			bits=16;
1433 		outchp++;
1434 		udf_chars++;
1435 	}
1436 	/* null terminate just in case */
1437 	*outchp++ = 0;
1438 
1439 	is_osta_typ0  = (chsp->type == 0);
1440 	is_osta_typ0 &= (strcmp((char *) chsp->inf, osta_id) == 0);
1441 	if (is_osta_typ0) {
1442 		udf_chars = udf_CompressUnicode(udf_chars, bits,
1443 				(unicode_t *) raw_name,
1444 				(byte *) result);
1445 	} else {
1446 		printf("unix to udf name: no CHSP0 ?\n");
1447 		/* XXX assume 8bit char length byte latin-1 */
1448 		*result++ = 8; udf_chars = 1;
1449 		strncpy(result, name + 1, name_len);
1450 		udf_chars += name_len;
1451 	}
1452 	*result_len = udf_chars;
1453 	free(raw_name);
1454 }
1455 
1456 
1457 #define UDF_SYMLINKBUFLEN    (64*1024)               /* picked */
1458 int
1459 udf_encode_symlink(uint8_t **pathbufp, uint32_t *pathlenp, char *target)
1460 {
1461 	struct charspec osta_charspec;
1462 	struct pathcomp pathcomp;
1463 	char *pathbuf, *pathpos, *compnamepos;
1464 //	char *mntonname;
1465 //	int   mntonnamelen;
1466 	int pathlen, len, compnamelen;
1467 	int error;
1468 
1469 	/* process `target' to an UDF structure */
1470 	pathbuf = malloc(UDF_SYMLINKBUFLEN);
1471 	assert(pathbuf);
1472 
1473 	*pathbufp = NULL;
1474 	*pathlenp = 0;
1475 
1476 	pathpos = pathbuf;
1477 	pathlen = 0;
1478 	udf_osta_charset(&osta_charspec);
1479 
1480 	if (*target == '/') {
1481 		/* symlink starts from the root */
1482 		len = UDF_PATH_COMP_SIZE;
1483 		memset(&pathcomp, 0, len);
1484 		pathcomp.type = UDF_PATH_COMP_ROOT;
1485 
1486 #if 0
1487 		/* XXX how to check for in makefs? */
1488 		/* check if its mount-point relative! */
1489 		mntonname    = udf_node->ump->vfs_mountp->mnt_stat.f_mntonname;
1490 		mntonnamelen = strlen(mntonname);
1491 		if (strlen(target) >= mntonnamelen) {
1492 			if (strncmp(target, mntonname, mntonnamelen) == 0) {
1493 				pathcomp.type = UDF_PATH_COMP_MOUNTROOT;
1494 				target += mntonnamelen;
1495 			}
1496 		} else {
1497 			target++;
1498 		}
1499 #else
1500 		target++;
1501 #endif
1502 
1503 		memcpy(pathpos, &pathcomp, len);
1504 		pathpos += len;
1505 		pathlen += len;
1506 	}
1507 
1508 	error = 0;
1509 	while (*target) {
1510 		/* ignore multiple '/' */
1511 		while (*target == '/') {
1512 			target++;
1513 		}
1514 		if (!*target)
1515 			break;
1516 
1517 		/* extract component name */
1518 		compnamelen = 0;
1519 		compnamepos = target;
1520 		while ((*target) && (*target != '/')) {
1521 			target++;
1522 			compnamelen++;
1523 		}
1524 
1525 		/* just trunc if too long ?? (security issue) */
1526 		if (compnamelen >= 127) {
1527 			error = ENAMETOOLONG;
1528 			break;
1529 		}
1530 
1531 		/* convert unix name to UDF name */
1532 		len = sizeof(struct pathcomp);
1533 		memset(&pathcomp, 0, len);
1534 		pathcomp.type = UDF_PATH_COMP_NAME;
1535 		len = UDF_PATH_COMP_SIZE;
1536 
1537 		if ((compnamelen == 2) && (strncmp(compnamepos, "..", 2) == 0))
1538 			pathcomp.type = UDF_PATH_COMP_PARENTDIR;
1539 		if ((compnamelen == 1) && (*compnamepos == '.'))
1540 			pathcomp.type = UDF_PATH_COMP_CURDIR;
1541 
1542 		if (pathcomp.type == UDF_PATH_COMP_NAME) {
1543 			unix_to_udf_name(
1544 				(char *) &pathcomp.ident, &pathcomp.l_ci,
1545 				compnamepos, compnamelen,
1546 				&osta_charspec);
1547 			len = UDF_PATH_COMP_SIZE + pathcomp.l_ci;
1548 		}
1549 
1550 		if (pathlen + len >= UDF_SYMLINKBUFLEN) {
1551 			error = ENAMETOOLONG;
1552 			break;
1553 		}
1554 
1555 		memcpy(pathpos, &pathcomp, len);
1556 		pathpos += len;
1557 		pathlen += len;
1558 	}
1559 
1560 	if (error) {
1561 		/* aparently too big */
1562 		free(pathbuf);
1563 		return error;
1564 	}
1565 
1566 	/* return status of symlink contents writeout */
1567 	*pathbufp = (uint8_t *) pathbuf;
1568 	*pathlenp = pathlen;
1569 
1570 	return 0;
1571 
1572 }
1573 #undef UDF_SYMLINKBUFLEN
1574 
1575 
1576 int
1577 udf_fidsize(struct fileid_desc *fid)
1578 {
1579 	uint32_t size;
1580 
1581 	if (udf_rw16(fid->tag.id) != TAGID_FID)
1582 		errx(EINVAL, "got udf_fidsize on non FID");
1583 
1584 	size = UDF_FID_SIZE + fid->l_fi + udf_rw16(fid->l_iu);
1585 	size = (size + 3) & ~3;
1586 
1587 	return size;
1588 }
1589 
1590 
1591 int
1592 udf_create_parentfid(struct fileid_desc *fid, struct long_ad *parent)
1593 {
1594 	/* the size of an empty FID is 38 but needs to be a multiple of 4 */
1595 	int fidsize = 40;
1596 
1597 	udf_inittag(&fid->tag, TAGID_FID, udf_rw32(parent->loc.lb_num));
1598 	fid->file_version_num = udf_rw16(1);	/* UDF 2.3.4.1 */
1599 	fid->file_char = UDF_FILE_CHAR_DIR | UDF_FILE_CHAR_PAR;
1600 	fid->icb = *parent;
1601 	fid->icb.longad_uniqueid = parent->longad_uniqueid;
1602 	fid->tag.desc_crc_len = udf_rw16(fidsize - UDF_DESC_TAG_LENGTH);
1603 
1604 	/* we have to do the fid here explicitly for simplicity */
1605 	udf_validate_tag_and_crc_sums((union dscrptr *) fid);
1606 
1607 	return fidsize;
1608 }
1609 
1610 
1611 void
1612 udf_create_fid(uint32_t diroff, struct fileid_desc *fid, char *name,
1613 	int file_char, struct long_ad *ref)
1614 {
1615 	struct charspec osta_charspec;
1616 	uint32_t endfid;
1617 	uint32_t fidsize, lb_rest;
1618 
1619 	memset(fid, 0, sizeof(*fid));
1620 	udf_inittag(&fid->tag, TAGID_FID, udf_rw32(ref->loc.lb_num));
1621 	fid->file_version_num = udf_rw16(1);	/* UDF 2.3.4.1 */
1622 	fid->file_char = file_char;
1623 	fid->l_iu = udf_rw16(0);
1624 	fid->icb = *ref;
1625 	fid->icb.longad_uniqueid = ref->longad_uniqueid;
1626 
1627 	udf_osta_charset(&osta_charspec);
1628 	unix_to_udf_name((char *) fid->data, &fid->l_fi, name, strlen(name),
1629 			&osta_charspec);
1630 
1631 	/*
1632 	 * OK, tricky part: we need to pad so the next descriptor header won't
1633 	 * cross the sector boundary
1634 	 */
1635 	endfid = diroff + udf_fidsize(fid);
1636 	lb_rest = context.sector_size - (endfid % context.sector_size);
1637 	if (lb_rest < sizeof(struct desc_tag)) {
1638 		/* add at least 32 */
1639 		fid->l_iu = udf_rw16(32);
1640 		udf_set_regid((struct regid *) fid->data, context.impl_name);
1641 		udf_add_impl_regid((struct regid *) fid->data);
1642 
1643 		unix_to_udf_name((char *) fid->data + udf_rw16(fid->l_iu),
1644 			&fid->l_fi, name, strlen(name), &osta_charspec);
1645 	}
1646 
1647 	fidsize = udf_fidsize(fid);
1648 	fid->tag.desc_crc_len = udf_rw16(fidsize - UDF_DESC_TAG_LENGTH);
1649 
1650 	/* make sure the header sums stays correct */
1651 	udf_validate_tag_and_crc_sums((union dscrptr *)fid);
1652 }
1653 
1654 
1655 static void
1656 udf_append_parentfid(union dscrptr *dscr, struct long_ad *parent_icb)
1657 {
1658 	struct file_entry      *fe;
1659 	struct extfile_entry   *efe;
1660 	struct fileid_desc     *fid;
1661 	uint32_t l_ea;
1662 	uint32_t fidsize, crclen;
1663 	uint8_t *bpos, *data;
1664 
1665 	fe = NULL;
1666 	efe = NULL;
1667 	if (udf_rw16(dscr->tag.id) == TAGID_FENTRY) {
1668 		fe    = &dscr->fe;
1669 		data  = fe->data;
1670 		l_ea  = udf_rw32(fe->l_ea);
1671 	} else if (udf_rw16(dscr->tag.id) == TAGID_EXTFENTRY) {
1672 		efe   = &dscr->efe;
1673 		data  = efe->data;
1674 		l_ea  = udf_rw32(efe->l_ea);
1675 	} else {
1676 		errx(1, "Bad tag passed to udf_append_parentfid");
1677 	}
1678 
1679 	/* create '..' */
1680 	bpos = data + l_ea;
1681 	fid  = (struct fileid_desc *) bpos;
1682 	fidsize = udf_create_parentfid(fid, parent_icb);
1683 
1684 	/* record fidlength information */
1685 	if (fe) {
1686 		fe->inf_len     = udf_rw64(fidsize);
1687 		fe->l_ad        = udf_rw32(fidsize);
1688 		fe->logblks_rec = udf_rw64(0);		/* intern */
1689 		crclen  = sizeof(struct file_entry);
1690 	} else {
1691 		efe->inf_len     = udf_rw64(fidsize);
1692 		efe->obj_size    = udf_rw64(fidsize);
1693 		efe->l_ad        = udf_rw32(fidsize);
1694 		efe->logblks_rec = udf_rw64(0);		/* intern */
1695 		crclen  = sizeof(struct extfile_entry);
1696 	}
1697 	crclen -= 1 + UDF_DESC_TAG_LENGTH;
1698 	crclen += l_ea + fidsize;
1699 	dscr->tag.desc_crc_len = udf_rw16(crclen);
1700 
1701 	/* make sure the header sums stays correct */
1702 	udf_validate_tag_and_crc_sums(dscr);
1703 }
1704 
1705 
1706 
1707 /*
1708  * Order of extended attributes :
1709  *   ECMA 167 EAs
1710  *   Non block aligned Implementation Use EAs
1711  *   Block aligned Implementation Use EAs	(not in newfs_udf)
1712  *   Application Use EAs			(not in newfs_udf)
1713  *
1714  *   no checks for doubles, must be called in-order
1715  */
1716 static void
1717 udf_extattr_append_internal(union dscrptr *dscr, struct extattr_entry *extattr)
1718 {
1719 	struct file_entry      *fe;
1720 	struct extfile_entry   *efe;
1721 	struct extattrhdr_desc *extattrhdr;
1722 	struct impl_extattr_entry *implext;
1723 	uint32_t impl_attr_loc, appl_attr_loc, l_ea, a_l, exthdr_len;
1724 	uint32_t *l_eap, l_ad;
1725 	uint16_t *spos;
1726 	uint8_t *bpos, *data;
1727 
1728 	if (udf_rw16(dscr->tag.id) == TAGID_FENTRY) {
1729 		fe    = &dscr->fe;
1730 		data  = fe->data;
1731 		l_eap = &fe->l_ea;
1732 		l_ad  = udf_rw32(fe->l_ad);
1733 	} else if (udf_rw16(dscr->tag.id) == TAGID_EXTFENTRY) {
1734 		efe   = &dscr->efe;
1735 		data  = efe->data;
1736 		l_eap = &efe->l_ea;
1737 		l_ad  = udf_rw32(efe->l_ad);
1738 	} else {
1739 		errx(1, "Bad tag passed to udf_extattr_append_internal");
1740 	}
1741 
1742 	/* should have a header! */
1743 	extattrhdr = (struct extattrhdr_desc *) data;
1744 	l_ea = udf_rw32(*l_eap);
1745 	if (l_ea == 0) {
1746 		assert(l_ad == 0);
1747 		/* create empty extended attribute header */
1748 		exthdr_len = sizeof(struct extattrhdr_desc);
1749 
1750 		udf_inittag(&extattrhdr->tag, TAGID_EXTATTR_HDR, /* loc */ 0);
1751 		extattrhdr->impl_attr_loc = udf_rw32(exthdr_len);
1752 		extattrhdr->appl_attr_loc = udf_rw32(exthdr_len);
1753 		extattrhdr->tag.desc_crc_len = udf_rw16(8);
1754 
1755 		/* record extended attribute header length */
1756 		l_ea = exthdr_len;
1757 		*l_eap = udf_rw32(l_ea);
1758 	}
1759 
1760 	/* extract locations */
1761 	impl_attr_loc = udf_rw32(extattrhdr->impl_attr_loc);
1762 	appl_attr_loc = udf_rw32(extattrhdr->appl_attr_loc);
1763 	if (impl_attr_loc == UDF_IMPL_ATTR_LOC_NOT_PRESENT)
1764 		impl_attr_loc = l_ea;
1765 	if (appl_attr_loc == UDF_IMPL_ATTR_LOC_NOT_PRESENT)
1766 		appl_attr_loc = l_ea;
1767 
1768 	/* Ecma 167 EAs */
1769 	if (udf_rw32(extattr->type) < 2048) {
1770 		assert(impl_attr_loc == l_ea);
1771 		assert(appl_attr_loc == l_ea);
1772 	}
1773 
1774 	/* implementation use extended attributes */
1775 	if (udf_rw32(extattr->type) == 2048) {
1776 		assert(appl_attr_loc == l_ea);
1777 
1778 		/* calculate and write extended attribute header checksum */
1779 		implext = (struct impl_extattr_entry *) extattr;
1780 		assert(udf_rw32(implext->iu_l) == 4);	/* [UDF 3.3.4.5] */
1781 		spos = (uint16_t *) implext->data;
1782 		*spos = udf_rw16(udf_ea_cksum((uint8_t *) implext));
1783 	}
1784 
1785 	/* application use extended attributes */
1786 	assert(udf_rw32(extattr->type) != 65536);
1787 	assert(appl_attr_loc == l_ea);
1788 
1789 	/* append the attribute at the end of the current space */
1790 	bpos = data + udf_rw32(*l_eap);
1791 	a_l  = udf_rw32(extattr->a_l);
1792 
1793 	/* update impl. attribute locations */
1794 	if (udf_rw32(extattr->type) < 2048) {
1795 		impl_attr_loc = l_ea + a_l;
1796 		appl_attr_loc = l_ea + a_l;
1797 	}
1798 	if (udf_rw32(extattr->type) == 2048) {
1799 		appl_attr_loc = l_ea + a_l;
1800 	}
1801 
1802 	/* copy and advance */
1803 	memcpy(bpos, extattr, a_l);
1804 	l_ea += a_l;
1805 	*l_eap = udf_rw32(l_ea);
1806 
1807 	/* do the `dance` again backwards */
1808 	if (context.dscrver != 2) {
1809 		if (impl_attr_loc == l_ea)
1810 			impl_attr_loc = UDF_IMPL_ATTR_LOC_NOT_PRESENT;
1811 		if (appl_attr_loc == l_ea)
1812 			appl_attr_loc = UDF_APPL_ATTR_LOC_NOT_PRESENT;
1813 	}
1814 
1815 	/* store offsets */
1816 	extattrhdr->impl_attr_loc = udf_rw32(impl_attr_loc);
1817 	extattrhdr->appl_attr_loc = udf_rw32(appl_attr_loc);
1818 
1819 	/* make sure the header sums stays correct */
1820 	udf_validate_tag_and_crc_sums((union dscrptr *) extattrhdr);
1821 }
1822 
1823 
1824 int
1825 udf_create_new_fe(struct file_entry **fep, int file_type, struct stat *st)
1826 {
1827 	struct file_entry      *fe;
1828 	struct icb_tag         *icb;
1829 	struct timestamp        birthtime;
1830 	struct filetimes_extattr_entry *ft_extattr;
1831 	uint32_t crclen;	/* XXX: should be 16; need to detect overflow */
1832 	uint16_t icbflags;
1833 
1834 	*fep = NULL;
1835 	fe = calloc(1, context.sector_size);
1836 	if (fe == NULL)
1837 		return ENOMEM;
1838 
1839 	udf_inittag(&fe->tag, TAGID_FENTRY, /* loc */ 0);
1840 	icb = &fe->icbtag;
1841 
1842 	/*
1843 	 * Always use strategy type 4 unless on WORM wich we don't support
1844 	 * (yet). Fill in defaults and set for internal allocation of data.
1845 	 */
1846 	icb->strat_type      = udf_rw16(4);
1847 	icb->max_num_entries = udf_rw16(1);
1848 	icb->file_type       = file_type;	/* 8 bit */
1849 	icb->flags           = udf_rw16(UDF_ICB_INTERN_ALLOC);
1850 
1851 	fe->perm     = udf_rw32(0x7fff);	/* all is allowed   */
1852 	fe->link_cnt = udf_rw16(0);		/* explicit setting */
1853 
1854 	fe->ckpoint  = udf_rw32(1);		/* user supplied file version */
1855 
1856 	udf_set_timestamp_now(&birthtime);
1857 	udf_set_timestamp_now(&fe->atime);
1858 	udf_set_timestamp_now(&fe->attrtime);
1859 	udf_set_timestamp_now(&fe->mtime);
1860 
1861 	/* set attributes */
1862 	if (st) {
1863 #if !HAVE_NBTOOL_CONFIG_H
1864 		udf_set_timestamp(&birthtime,    st->st_birthtime);
1865 #else
1866 		udf_set_timestamp(&birthtime,    0);
1867 #endif
1868 		udf_set_timestamp(&fe->atime,    st->st_atime);
1869 		udf_set_timestamp(&fe->attrtime, st->st_ctime);
1870 		udf_set_timestamp(&fe->mtime,    st->st_mtime);
1871 		fe->uid  = udf_rw32(st->st_uid);
1872 		fe->gid  = udf_rw32(st->st_gid);
1873 
1874 		fe->perm = unix_mode_to_udf_perm(st->st_mode);
1875 
1876 		icbflags = udf_rw16(fe->icbtag.flags);
1877 		icbflags &= ~UDF_ICB_TAG_FLAGS_SETUID;
1878 		icbflags &= ~UDF_ICB_TAG_FLAGS_SETGID;
1879 		icbflags &= ~UDF_ICB_TAG_FLAGS_STICKY;
1880 		if (st->st_mode & S_ISUID)
1881 			icbflags |= UDF_ICB_TAG_FLAGS_SETUID;
1882 		if (st->st_mode & S_ISGID)
1883 			icbflags |= UDF_ICB_TAG_FLAGS_SETGID;
1884 		if (st->st_mode & S_ISVTX)
1885 			icbflags |= UDF_ICB_TAG_FLAGS_STICKY;
1886 		fe->icbtag.flags  = udf_rw16(icbflags);
1887 	}
1888 
1889 	udf_set_regid(&fe->imp_id, context.impl_name);
1890 	udf_add_impl_regid(&fe->imp_id);
1891 	fe->unique_id = udf_rw64(context.unique_id);
1892 	udf_advance_uniqueid();
1893 
1894 	fe->l_ea = udf_rw32(0);
1895 
1896 	/* create extended attribute to record our creation time */
1897 	ft_extattr = calloc(1, UDF_FILETIMES_ATTR_SIZE(1));
1898 	ft_extattr->hdr.type = udf_rw32(UDF_FILETIMES_ATTR_NO);
1899 	ft_extattr->hdr.subtype = 1;	/* [4/48.10.5] */
1900 	ft_extattr->hdr.a_l = udf_rw32(UDF_FILETIMES_ATTR_SIZE(1));
1901 	ft_extattr->d_l     = udf_rw32(UDF_TIMESTAMP_SIZE); /* one item */
1902 	ft_extattr->existence = UDF_FILETIMES_FILE_CREATION;
1903 	ft_extattr->times[0]  = birthtime;
1904 
1905 	udf_extattr_append_internal((union dscrptr *) fe,
1906 		(struct extattr_entry *) ft_extattr);
1907 	free(ft_extattr);
1908 
1909 	/* record fidlength information */
1910 	fe->inf_len = udf_rw64(0);
1911 	fe->l_ad    = udf_rw32(0);
1912 	fe->logblks_rec = udf_rw64(0);		/* intern */
1913 
1914 	crclen  = sizeof(struct file_entry) - 1 - UDF_DESC_TAG_LENGTH;
1915 	crclen += udf_rw32(fe->l_ea);
1916 
1917 	/* make sure the header sums stays correct */
1918 	fe->tag.desc_crc_len = udf_rw16(crclen);
1919 	udf_validate_tag_and_crc_sums((union dscrptr *) fe);
1920 
1921 	*fep = fe;
1922 	return 0;
1923 }
1924 
1925 
1926 int
1927 udf_create_new_efe(struct extfile_entry **efep, int file_type, struct stat *st)
1928 {
1929 	struct extfile_entry *efe;
1930 	struct icb_tag       *icb;
1931 	uint32_t crclen;	/* XXX: should be 16; need to detect overflow */
1932 	uint16_t icbflags;
1933 
1934 	*efep = NULL;
1935 	efe = calloc(1, context.sector_size);
1936 	if (efe == NULL)
1937 		return ENOMEM;
1938 
1939 	udf_inittag(&efe->tag, TAGID_EXTFENTRY, /* loc */ 0);
1940 	icb = &efe->icbtag;
1941 
1942 	/*
1943 	 * Always use strategy type 4 unless on WORM wich we don't support
1944 	 * (yet). Fill in defaults and set for internal allocation of data.
1945 	 */
1946 	icb->strat_type      = udf_rw16(4);
1947 	icb->max_num_entries = udf_rw16(1);
1948 	icb->file_type       = file_type;	/* 8 bit */
1949 	icb->flags = udf_rw16(UDF_ICB_INTERN_ALLOC);
1950 
1951 	efe->perm     = udf_rw32(0x7fff);	/* all is allowed   */
1952 	efe->link_cnt = udf_rw16(0);		/* explicit setting */
1953 
1954 	efe->ckpoint  = udf_rw32(1);		/* user supplied file version */
1955 
1956 	udf_set_timestamp_now(&efe->ctime);
1957 	udf_set_timestamp_now(&efe->atime);
1958 	udf_set_timestamp_now(&efe->attrtime);
1959 	udf_set_timestamp_now(&efe->mtime);
1960 
1961 	/* set attributes */
1962 	if (st) {
1963 #if !HAVE_NBTOOL_CONFIG_H
1964 		udf_set_timestamp(&efe->ctime,    st->st_birthtime);
1965 #else
1966 		udf_set_timestamp(&efe->ctime,    0);
1967 #endif
1968 		udf_set_timestamp(&efe->atime,    st->st_atime);
1969 		udf_set_timestamp(&efe->attrtime, st->st_ctime);
1970 		udf_set_timestamp(&efe->mtime,    st->st_mtime);
1971 		efe->uid = udf_rw32(st->st_uid);
1972 		efe->gid = udf_rw32(st->st_gid);
1973 
1974 		efe->perm = unix_mode_to_udf_perm(st->st_mode);
1975 
1976 		icbflags = udf_rw16(efe->icbtag.flags);
1977 		icbflags &= ~UDF_ICB_TAG_FLAGS_SETUID;
1978 		icbflags &= ~UDF_ICB_TAG_FLAGS_SETGID;
1979 		icbflags &= ~UDF_ICB_TAG_FLAGS_STICKY;
1980 		if (st->st_mode & S_ISUID)
1981 			icbflags |= UDF_ICB_TAG_FLAGS_SETUID;
1982 		if (st->st_mode & S_ISGID)
1983 			icbflags |= UDF_ICB_TAG_FLAGS_SETGID;
1984 		if (st->st_mode & S_ISVTX)
1985 			icbflags |= UDF_ICB_TAG_FLAGS_STICKY;
1986 		efe->icbtag.flags = udf_rw16(icbflags);
1987 	}
1988 
1989 	udf_set_regid(&efe->imp_id, context.impl_name);
1990 	udf_add_impl_regid(&efe->imp_id);
1991 
1992 	efe->unique_id = udf_rw64(context.unique_id);
1993 	udf_advance_uniqueid();
1994 
1995 	/* record fidlength information */
1996 	efe->inf_len  = udf_rw64(0);
1997 	efe->obj_size = udf_rw64(0);
1998 	efe->l_ad     = udf_rw32(0);
1999 	efe->logblks_rec = udf_rw64(0);
2000 
2001 	crclen  = sizeof(struct extfile_entry) - 1 - UDF_DESC_TAG_LENGTH;
2002 
2003 	/* make sure the header sums stays correct */
2004 	efe->tag.desc_crc_len = udf_rw16(crclen);
2005 	udf_validate_tag_and_crc_sums((union dscrptr *) efe);
2006 
2007 	*efep = efe;
2008 	return 0;
2009 }
2010 
2011 /* --------------------------------------------------------------------- */
2012 
2013 /* for METADATA file appending only */
2014 static void
2015 udf_append_meta_mapping_part_to_efe(struct extfile_entry *efe,
2016 		struct short_ad *mapping)
2017 {
2018 	struct icb_tag *icb;
2019 	uint64_t inf_len, obj_size, logblks_rec;
2020 	uint32_t l_ad, l_ea;
2021 	uint16_t crclen;
2022 	uint8_t *bpos;
2023 
2024 	inf_len     = udf_rw64(efe->inf_len);
2025 	obj_size    = udf_rw64(efe->obj_size);
2026 	logblks_rec = udf_rw64(efe->logblks_rec);
2027 	l_ad   = udf_rw32(efe->l_ad);
2028 	l_ea   = udf_rw32(efe->l_ea);
2029 	crclen = udf_rw16(efe->tag.desc_crc_len);
2030 	icb    = &efe->icbtag;
2031 
2032 	/* set our allocation to shorts if not already done */
2033 	icb->flags = udf_rw16(UDF_ICB_SHORT_ALLOC);
2034 
2035 	/* append short_ad */
2036 	bpos = (uint8_t *) efe->data + l_ea + l_ad;
2037 	memcpy(bpos, mapping, sizeof(struct short_ad));
2038 
2039 	l_ad   += sizeof(struct short_ad);
2040 	crclen += sizeof(struct short_ad);
2041 	inf_len  += UDF_EXT_LEN(udf_rw32(mapping->len));
2042 	obj_size += UDF_EXT_LEN(udf_rw32(mapping->len));
2043 	logblks_rec = UDF_ROUNDUP(inf_len, context.sector_size) /
2044 				context.sector_size;
2045 
2046 	efe->l_ad = udf_rw32(l_ad);
2047 	efe->inf_len     = udf_rw64(inf_len);
2048 	efe->obj_size    = udf_rw64(obj_size);
2049 	efe->logblks_rec = udf_rw64(logblks_rec);
2050 	efe->tag.desc_crc_len = udf_rw16(crclen);
2051 }
2052 
2053 
2054 /* for METADATA file appending only */
2055 static void
2056 udf_append_meta_mapping_to_efe(struct extfile_entry *efe,
2057 		uint16_t partnr, uint32_t lb_num,
2058 	uint64_t len)
2059 {
2060 	struct short_ad mapping;
2061 	uint64_t max_len, part_len;
2062 
2063 	/* calculate max length meta allocation sizes */
2064 	max_len = UDF_EXT_MAXLEN / context.sector_size; /* in sectors */
2065 	max_len = (max_len / layout.meta_blockingnr) * layout.meta_blockingnr;
2066 	max_len = max_len * context.sector_size;
2067 
2068 	memset(&mapping, 0, sizeof(mapping));
2069 	while (len) {
2070 		part_len = MIN(len, max_len);
2071 		mapping.lb_num   = udf_rw32(lb_num);
2072 		mapping.len      = udf_rw32(part_len);
2073 
2074 		udf_append_meta_mapping_part_to_efe(efe, &mapping);
2075 
2076 		lb_num += part_len / context.sector_size;
2077 		len    -= part_len;
2078 	}
2079 }
2080 
2081 
2082 int
2083 udf_create_meta_files(void)
2084 {
2085 	struct extfile_entry *efe;
2086 	struct long_ad meta_icb;
2087 	uint64_t bytes;
2088 	uint32_t sector_size;
2089 	int filetype, error;
2090 
2091 	sector_size = context.sector_size;
2092 
2093 	memset(&meta_icb, 0, sizeof(meta_icb));
2094 	meta_icb.len          = udf_rw32(sector_size);
2095 	meta_icb.loc.part_num = udf_rw16(context.data_part);
2096 
2097 	/* create metadata file */
2098 	meta_icb.loc.lb_num   = udf_rw32(layout.meta_file);
2099 	filetype = UDF_ICB_FILETYPE_META_MAIN;
2100 	error = udf_create_new_efe(&efe, filetype, NULL);
2101 	if (error)
2102 		return error;
2103 	context.meta_file = efe;
2104 
2105 	/* create metadata mirror file */
2106 	meta_icb.loc.lb_num   = udf_rw32(layout.meta_mirror);
2107 	filetype = UDF_ICB_FILETYPE_META_MIRROR;
2108 	error = udf_create_new_efe(&efe, filetype, NULL);
2109 	if (error)
2110 		return error;
2111 	context.meta_mirror = efe;
2112 
2113 	/* create metadata bitmap file */
2114 	meta_icb.loc.lb_num   = udf_rw32(layout.meta_bitmap);
2115 	filetype = UDF_ICB_FILETYPE_META_BITMAP;
2116 	error = udf_create_new_efe(&efe, filetype, NULL);
2117 	if (error)
2118 		return error;
2119 	context.meta_bitmap = efe;
2120 
2121 	/* patch up files */
2122 	context.meta_file->unique_id   = udf_rw64(0);
2123 	context.meta_mirror->unique_id = udf_rw64(0);
2124 	context.meta_bitmap->unique_id = udf_rw64(0);
2125 
2126 	/* restart unique id */
2127 	context.unique_id = 0x10;
2128 
2129 	/* XXX no support for metadata mirroring yet */
2130 	/* insert extents */
2131 	efe = context.meta_file;
2132 	udf_append_meta_mapping_to_efe(efe, context.data_part,
2133 		layout.meta_part_start_lba,
2134 		(uint64_t) layout.meta_part_size_lba * sector_size);
2135 
2136 	efe = context.meta_mirror;
2137 	udf_append_meta_mapping_to_efe(efe, context.data_part,
2138 		layout.meta_part_start_lba,
2139 		(uint64_t) layout.meta_part_size_lba * sector_size);
2140 
2141 	efe = context.meta_bitmap;
2142 	bytes = udf_space_bitmap_len(layout.meta_part_size_lba);
2143 	udf_append_meta_mapping_to_efe(efe, context.data_part,
2144 		layout.meta_bitmap_space, bytes);
2145 
2146 	return 0;
2147 }
2148 
2149 
2150 /* --------------------------------------------------------------------- */
2151 
2152 int
2153 udf_create_new_rootdir(union dscrptr **dscr)
2154 {
2155 	struct file_entry *fe;
2156 	struct extfile_entry *efe;
2157 	struct long_ad root_icb;
2158 	int filetype, error;
2159 
2160 	memset(&root_icb, 0, sizeof(root_icb));
2161 	root_icb.len          = udf_rw32(context.sector_size);
2162 	root_icb.loc.lb_num   = udf_rw32(layout.rootdir);
2163 	root_icb.loc.part_num = udf_rw16(context.metadata_part);
2164 
2165 	filetype = UDF_ICB_FILETYPE_DIRECTORY;
2166 	if (context.dscrver == 2) {
2167 		error = udf_create_new_fe(&fe, filetype, NULL);
2168 		*dscr = (union dscrptr *) fe;
2169 	} else {
2170 		error = udf_create_new_efe(&efe, filetype, NULL);
2171 		*dscr = (union dscrptr *) efe;
2172 	}
2173 	if (error)
2174 		return error;
2175 
2176 	/* append '..' */
2177 	udf_append_parentfid(*dscr, &root_icb);
2178 
2179 	/* rootdir has explicit only one link on creation; '..' is no link */
2180 	if (context.dscrver == 2) {
2181 		fe->link_cnt  = udf_rw16(1);
2182 	} else {
2183 		efe->link_cnt = udf_rw16(1);
2184 	}
2185 
2186 	context.num_directories++;
2187 	assert(context.num_directories == 1);
2188 
2189 	return 0;
2190 }
2191 
2192 
2193 void
2194 udf_prepend_VAT_file(void)
2195 {
2196 	/* old style VAT has no prepend */
2197 	if (context.dscrver == 2) {
2198 		context.vat_start = 0;
2199 		context.vat_size  = 0;
2200 		return;
2201 	}
2202 
2203 	context.vat_start = offsetof(struct udf_vat, data);
2204 	context.vat_size  = offsetof(struct udf_vat, data);
2205 }
2206 
2207 
2208 void
2209 udf_vat_update(uint32_t virt, uint32_t phys)
2210 {
2211 	uint32_t *vatpos;
2212 	uint32_t new_size;
2213 
2214 	if (context.vtop_tp[context.metadata_part] != UDF_VTOP_TYPE_VIRT)
2215 		return;
2216 
2217 	new_size = MAX(context.vat_size,
2218 		(context.vat_start + (virt+1)*sizeof(uint32_t)));
2219 
2220 	if (new_size > context.vat_allocated) {
2221 		context.vat_allocated =
2222 			UDF_ROUNDUP(new_size, context.sector_size);
2223 		context.vat_contents = realloc(context.vat_contents,
2224 			context.vat_allocated);
2225 		assert(context.vat_contents);
2226 		/* XXX could also report error */
2227 	}
2228 	vatpos  = (uint32_t *) (context.vat_contents + context.vat_start);
2229 	vatpos[virt] = udf_rw32(phys);
2230 
2231 	context.vat_size = MAX(context.vat_size,
2232 		(context.vat_start + (virt+1)*sizeof(uint32_t)));
2233 }
2234 
2235 
2236 int
2237 udf_append_VAT_file(void)
2238 {
2239 	struct udf_oldvat_tail *oldvat_tail;
2240 	struct udf_vat *vathdr;
2241 	int32_t len_diff;
2242 
2243 	/* new style VAT has VAT LVInt analog in front */
2244 	if (context.dscrver == 3) {
2245 		/* set up VATv2 descriptor */
2246 		vathdr = (struct udf_vat *) context.vat_contents;
2247 		vathdr->header_len      = udf_rw16(sizeof(struct udf_vat) - 1);
2248 		vathdr->impl_use_len    = udf_rw16(0);
2249 		memcpy(vathdr->logvol_id, context.logical_vol->logvol_id, 128);
2250 		vathdr->prev_vat        = udf_rw32(UDF_NO_PREV_VAT);
2251 		vathdr->num_files       = udf_rw32(context.num_files);
2252 		vathdr->num_directories = udf_rw32(context.num_directories);
2253 
2254 		vathdr->min_udf_readver  = udf_rw16(context.min_udf);
2255 		vathdr->min_udf_writever = udf_rw16(context.min_udf);
2256 		vathdr->max_udf_writever = udf_rw16(context.max_udf);
2257 
2258 		return 0;
2259 	}
2260 
2261 	/* old style VAT has identifier appended */
2262 
2263 	/* append "*UDF Virtual Alloc Tbl" id and prev. VAT location */
2264 	len_diff = context.vat_allocated - context.vat_size;
2265 	assert(len_diff >= 0);
2266 	if (len_diff < (int32_t) sizeof(struct udf_oldvat_tail)) {
2267 		context.vat_allocated += context.sector_size;
2268 		context.vat_contents = realloc(context.vat_contents,
2269 			context.vat_allocated);
2270 		assert(context.vat_contents);
2271 		/* XXX could also report error */
2272 	}
2273 
2274 	oldvat_tail = (struct udf_oldvat_tail *) (context.vat_contents +
2275 			context.vat_size);
2276 
2277 	udf_set_regid(&oldvat_tail->id, "*UDF Virtual Alloc Tbl");
2278 	udf_add_udf_regid(&oldvat_tail->id);
2279 	oldvat_tail->prev_vat = udf_rw32(UDF_NO_PREV_VAT);
2280 
2281 	context.vat_size += sizeof(struct udf_oldvat_tail);
2282 
2283 	return 0;
2284 }
2285 
2286 
2287 int
2288 udf_create_VAT(union dscrptr **vat_dscr)
2289 {
2290 	struct file_entry *fe;
2291 	struct extfile_entry *efe;
2292 	struct impl_extattr_entry *implext;
2293 	struct vatlvext_extattr_entry *vatlvext;
2294 	struct long_ad dataloc, *allocpos;
2295 	uint8_t *bpos, *extattr;
2296 	uint32_t ea_len, inf_len, vat_len, blks;
2297 	int filetype;
2298 	int error;
2299 
2300 	assert((layout.rootdir < 2) && (layout.fsd < 2));
2301 
2302 	memset(&dataloc, 0, sizeof(dataloc));
2303 	dataloc.len = udf_rw32(context.vat_size);
2304 	dataloc.loc.part_num = udf_rw16(context.data_part);
2305 	dataloc.loc.lb_num   = udf_rw32(layout.vat);
2306 
2307 	if (context.dscrver == 2) {
2308 		/* old style VAT */
2309 		filetype = UDF_ICB_FILETYPE_UNKNOWN;
2310 		error = udf_create_new_fe(&fe, filetype, NULL);
2311 		if (error)
2312 			return error;
2313 
2314 		/* append VAT LVExtension attribute */
2315 		ea_len = sizeof(struct impl_extattr_entry) - 1 +
2316 			 sizeof(struct vatlvext_extattr_entry) + 4;
2317 
2318 		extattr = calloc(1, ea_len);
2319 
2320 		implext  = (struct impl_extattr_entry *) extattr;
2321 		implext->hdr.type = udf_rw32(2048);	/* [4/48.10.8] */
2322 		implext->hdr.subtype = 1;		/* [4/48.10.8.2] */
2323 		implext->hdr.a_l = udf_rw32(ea_len);	/* VAT LVext EA size */
2324 		/* use 4 bytes of imp use for UDF checksum [UDF 3.3.4.5] */
2325 		implext->iu_l = udf_rw32(4);
2326 		udf_set_regid(&implext->imp_id, "*UDF VAT LVExtension");
2327 		udf_add_udf_regid(&implext->imp_id);
2328 
2329 		/* VAT LVExtension data follows UDF IU space */
2330 		bpos = ((uint8_t *) implext->data) + 4;
2331 		vatlvext = (struct vatlvext_extattr_entry *) bpos;
2332 
2333 		vatlvext->unique_id_chk = udf_rw64(fe->unique_id);
2334 		vatlvext->num_files = udf_rw32(context.num_files);
2335 		vatlvext->num_directories = udf_rw32(context.num_directories);
2336 		memcpy(vatlvext->logvol_id, context.logical_vol->logvol_id,128);
2337 
2338 		udf_extattr_append_internal((union dscrptr *) fe,
2339 			(struct extattr_entry *) extattr);
2340 
2341 		free(extattr);
2342 
2343 		fe->icbtag.flags = udf_rw16(UDF_ICB_LONG_ALLOC);
2344 
2345 		allocpos = (struct long_ad *) (fe->data + udf_rw32(fe->l_ea));
2346 		*allocpos = dataloc;
2347 
2348 		/* set length */
2349 		inf_len = context.vat_size;
2350 		fe->inf_len = udf_rw64(inf_len);
2351 		fe->l_ad    = udf_rw32(sizeof(struct long_ad));
2352 		blks = UDF_ROUNDUP(inf_len, context.sector_size) /
2353 			context.sector_size;
2354 		fe->logblks_rec = udf_rw32(blks);
2355 
2356 		/* update vat descriptor's CRC length */
2357 		vat_len  = sizeof(struct file_entry) - 1 - UDF_DESC_TAG_LENGTH;
2358 		vat_len += udf_rw32(fe->l_ad) + udf_rw32(fe->l_ea);
2359 		fe->tag.desc_crc_len = udf_rw16(vat_len);
2360 
2361 		*vat_dscr = (union dscrptr *) fe;
2362 	} else {
2363 		/* new style VAT */
2364 		filetype = UDF_ICB_FILETYPE_VAT;
2365 		error = udf_create_new_efe(&efe, filetype, NULL);
2366 		if (error)
2367 			return error;
2368 
2369 		efe->icbtag.flags = udf_rw16(UDF_ICB_LONG_ALLOC);
2370 
2371 		allocpos = (struct long_ad *) efe->data;
2372 		*allocpos = dataloc;
2373 
2374 		/* set length */
2375 		inf_len = context.vat_size;
2376 		efe->inf_len     = udf_rw64(inf_len);
2377 		efe->obj_size    = udf_rw64(inf_len);
2378 		efe->l_ad        = udf_rw32(sizeof(struct long_ad));
2379 		blks = UDF_ROUNDUP(inf_len, context.sector_size) /
2380 			context.sector_size;
2381 		efe->logblks_rec = udf_rw32(blks);
2382 
2383 		vat_len  = sizeof(struct extfile_entry)-1 - UDF_DESC_TAG_LENGTH;
2384 		vat_len += udf_rw32(efe->l_ad);
2385 		efe->tag.desc_crc_len = udf_rw16(vat_len);
2386 
2387 		*vat_dscr = (union dscrptr *) efe;
2388 	}
2389 
2390 	return 0;
2391 }
2392 
2393