1 /* $NetBSD: udf_write.c,v 1.9 2015/01/02 21:01:12 reinoud Exp $ */
4 * Copyright (c) 2006, 2008, 2013 Reinoud Zandijk
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
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.
28 #if HAVE_NBTOOL_CONFIG_H
29 #include "nbtool_config.h"
32 #include <sys/cdefs.h>
33 __RCSID("$NetBSD: udf_write.c,v 1.9 2015/01/02 21:01:12 reinoud Exp $");
42 #include <sys/types.h>
43 #include <sys/param.h>
45 #if !HAVE_NBTOOL_CONFIG_H
49 #include "udf/cdio_mmc_structs.h"
52 #include "udf_create.h"
53 #include "udf_write.h"
54 #include "newfs_udf.h"
57 union dscrptr
*terminator_dscr
;
60 udf_write_phys(void *blob
, uint32_t location
, uint32_t sects
)
66 for (cnt
= 0; cnt
< sects
; cnt
++) {
67 bpos
= (uint8_t *) blob
;
68 bpos
+= context
.sector_size
* cnt
;
70 phys
= location
+ cnt
;
71 error
= udf_write_sector(bpos
, phys
);
80 udf_write_dscr_phys(union dscrptr
*dscr
, uint32_t location
,
83 dscr
->tag
.tag_loc
= udf_rw32(location
);
84 (void) udf_validate_tag_and_crc_sums(dscr
);
86 return udf_write_phys(dscr
, location
, sects
);
91 udf_write_dscr_virt(union dscrptr
*dscr
, uint32_t location
, uint32_t vpart
,
94 struct file_entry
*fe
;
95 struct extfile_entry
*efe
;
96 struct extattrhdr_desc
*extattrhdr
;
100 if (udf_rw16(dscr
->tag
.id
) == TAGID_FENTRY
) {
101 fe
= (struct file_entry
*) dscr
;
102 if (udf_rw32(fe
->l_ea
) > 0)
103 extattrhdr
= (struct extattrhdr_desc
*) fe
->data
;
105 if (udf_rw16(dscr
->tag
.id
) == TAGID_EXTFENTRY
) {
106 efe
= (struct extfile_entry
*) dscr
;
107 if (udf_rw32(efe
->l_ea
) > 0)
108 extattrhdr
= (struct extattrhdr_desc
*) efe
->data
;
111 extattrhdr
->tag
.tag_loc
= udf_rw32(location
);
112 udf_validate_tag_and_crc_sums((union dscrptr
*) extattrhdr
);
115 dscr
->tag
.tag_loc
= udf_rw32(location
);
116 udf_validate_tag_and_crc_sums(dscr
);
118 /* determine physical location */
119 phys
= context
.vtop_offset
[vpart
];
120 if (context
.vtop_tp
[vpart
] == UDF_VTOP_TYPE_VIRT
) {
121 udf_vat_update(location
, context
.data_alloc_pos
);
122 phys
+= context
.data_alloc_pos
++;
127 return udf_write_phys(dscr
, phys
, sects
);
132 udf_metadata_alloc(int nblk
, struct long_ad
*pos
)
134 memset(pos
, 0, sizeof(*pos
));
135 pos
->len
= udf_rw32(nblk
* context
.sector_size
);
136 pos
->loc
.lb_num
= udf_rw32(context
.metadata_alloc_pos
);
137 pos
->loc
.part_num
= udf_rw16(context
.metadata_part
);
139 udf_mark_allocated(context
.metadata_alloc_pos
, context
.metadata_part
,
142 context
.metadata_alloc_pos
+= nblk
;
143 if (context
.metadata_part
== context
.data_part
)
144 context
.data_alloc_pos
= context
.metadata_alloc_pos
;
149 udf_data_alloc(int nblk
, struct long_ad
*pos
)
151 memset(pos
, 0, sizeof(*pos
));
152 pos
->len
= udf_rw32(nblk
* context
.sector_size
);
153 pos
->loc
.lb_num
= udf_rw32(context
.data_alloc_pos
);
154 pos
->loc
.part_num
= udf_rw16(context
.data_part
);
156 udf_mark_allocated(context
.data_alloc_pos
, context
.data_part
, nblk
);
157 context
.data_alloc_pos
+= nblk
;
158 if (context
.metadata_part
== context
.data_part
)
159 context
.metadata_alloc_pos
= context
.data_alloc_pos
;
164 /* --------------------------------------------------------------------- */
167 * udf_derive_format derives the format_flags from the disc's mmc_discinfo.
168 * The resulting flags uniquely define a disc format. Note there are at least
169 * 7 distinct format types defined in UDF.
172 #define UDF_VERSION(a) \
173 (((a) == 0x100) || ((a) == 0x102) || ((a) == 0x150) || ((a) == 0x200) || \
174 ((a) == 0x201) || ((a) == 0x250) || ((a) == 0x260))
177 udf_derive_format(int req_enable
, int req_disable
, int force
)
179 /* disc writability, formatted, appendable */
180 if ((mmc_discinfo
.mmc_cur
& MMC_CAP_RECORDABLE
) == 0) {
181 (void)printf("Can't newfs readonly device\n");
184 if (mmc_discinfo
.mmc_cur
& MMC_CAP_SEQUENTIAL
) {
185 /* sequentials need sessions appended */
186 if (mmc_discinfo
.disc_state
== MMC_STATE_CLOSED
) {
187 (void)printf("Can't append session to a closed disc\n");
190 if ((mmc_discinfo
.disc_state
!= MMC_STATE_EMPTY
) && !force
) {
191 (void)printf("Disc not empty! Use -F to force "
196 /* check if disc (being) formatted or has been started on */
197 if (mmc_discinfo
.disc_state
== MMC_STATE_EMPTY
) {
198 (void)printf("Disc is not formatted\n");
203 /* determine UDF format */
205 if (mmc_discinfo
.mmc_cur
& MMC_CAP_REWRITABLE
) {
206 /* all rewritable media */
207 format_flags
|= FORMAT_REWRITABLE
;
208 if (context
.min_udf
>= 0x0250) {
209 /* standard dictates meta as default */
210 format_flags
|= FORMAT_META
;
213 if ((mmc_discinfo
.mmc_cur
& MMC_CAP_HW_DEFECTFREE
) == 0) {
214 /* sparables for defect management */
215 if (context
.min_udf
>= 0x150)
216 format_flags
|= FORMAT_SPARABLE
;
219 /* all once recordable media */
220 format_flags
|= FORMAT_WRITEONCE
;
221 if (mmc_discinfo
.mmc_cur
& MMC_CAP_SEQUENTIAL
) {
222 format_flags
|= FORMAT_SEQUENTIAL
;
224 if (mmc_discinfo
.mmc_cur
& MMC_CAP_PSEUDOOVERWRITE
) {
225 /* logical overwritable */
226 format_flags
|= FORMAT_LOW
;
228 /* have to use VAT for overwriting */
229 format_flags
|= FORMAT_VAT
;
232 /* rare WORM devices, but BluRay has one, strat4096 */
233 format_flags
|= FORMAT_WORM
;
237 /* enable/disable requests */
238 if (req_disable
& FORMAT_META
) {
239 format_flags
&= ~(FORMAT_META
| FORMAT_LOW
);
240 req_disable
&= ~FORMAT_META
;
242 if ((format_flags
& FORMAT_VAT
) & UDF_512_TRACK
)
243 format_flags
|= FORMAT_TRACK512
;
245 if (req_enable
& FORMAT_READONLY
) {
246 format_flags
|= FORMAT_READONLY
;
249 /* determine partition/media access type */
250 media_accesstype
= UDF_ACCESSTYPE_NOT_SPECIFIED
;
251 if (mmc_discinfo
.mmc_cur
& MMC_CAP_REWRITABLE
) {
252 media_accesstype
= UDF_ACCESSTYPE_OVERWRITABLE
;
253 if (mmc_discinfo
.mmc_cur
& MMC_CAP_ERASABLE
)
254 media_accesstype
= UDF_ACCESSTYPE_REWRITEABLE
;
256 /* all once recordable media */
257 media_accesstype
= UDF_ACCESSTYPE_WRITE_ONCE
;
259 if (mmc_discinfo
.mmc_cur
& MMC_CAP_PSEUDOOVERWRITE
)
260 media_accesstype
= UDF_ACCESSTYPE_PSEUDO_OVERWITE
;
262 /* patch up media accesstype */
263 if (req_enable
& FORMAT_READONLY
) {
265 media_accesstype
= UDF_ACCESSTYPE_READ_ONLY
;
268 /* adjust minimum version limits */
269 if (format_flags
& FORMAT_VAT
)
270 context
.min_udf
= MAX(context
.min_udf
, 0x0150);
271 if (format_flags
& FORMAT_SPARABLE
)
272 context
.min_udf
= MAX(context
.min_udf
, 0x0150);
273 if (format_flags
& FORMAT_META
)
274 context
.min_udf
= MAX(context
.min_udf
, 0x0250);
275 if (format_flags
& FORMAT_LOW
)
276 context
.min_udf
= MAX(context
.min_udf
, 0x0260);
278 /* adjust maximum version limits not to tease or break things */
279 if (!(format_flags
& (FORMAT_META
| FORMAT_LOW
)) &&
280 (context
.max_udf
> 0x200))
281 context
.max_udf
= 0x201;
283 if ((format_flags
& (FORMAT_VAT
| FORMAT_SPARABLE
)) == 0)
284 if (context
.max_udf
<= 0x150)
285 context
.min_udf
= 0x102;
287 /* limit Ecma 167 descriptor if possible/needed */
289 if ((context
.min_udf
< 0x200) || (context
.max_udf
< 0x200)) {
291 context
.max_udf
= 0x150; /* last version < 0x200 */
294 /* is it possible ? */
295 if (context
.min_udf
> context
.max_udf
) {
296 (void)printf("Initialisation prohibited by specified maximum "
297 "UDF version 0x%04x. Minimum version required 0x%04x\n",
298 context
.max_udf
, context
.min_udf
);
302 if (!UDF_VERSION(context
.min_udf
) || !UDF_VERSION(context
.max_udf
)) {
303 printf("Choose UDF version numbers from "
304 "0x102, 0x150, 0x200, 0x201, 0x250 and 0x260\n");
305 printf("Default version is 0x201\n");
315 /* --------------------------------------------------------------------- */
318 udf_proces_names(void)
320 struct timeval time_of_day
;
324 if (context
.logvol_name
== NULL
)
325 context
.logvol_name
= strdup("anonymous");
326 if (context
.primary_name
== NULL
) {
327 if (mmc_discinfo
.disc_flags
& MMC_DFLAGS_DISCIDVALID
) {
328 primary_nr
= mmc_discinfo
.disc_id
;
330 primary_nr
= (uint32_t) random();
332 context
.primary_name
= calloc(32, 1);
333 sprintf(context
.primary_name
, "%08"PRIx32
, primary_nr
);
335 if (context
.volset_name
== NULL
) {
336 if (mmc_discinfo
.disc_flags
& MMC_DFLAGS_BARCODEVALID
) {
337 volset_nr
= mmc_discinfo
.disc_barcode
;
339 (void)gettimeofday(&time_of_day
, NULL
);
340 volset_nr
= (uint64_t) random();
341 volset_nr
|= ((uint64_t) time_of_day
.tv_sec
) << 32;
343 context
.volset_name
= calloc(128,1);
344 sprintf(context
.volset_name
, "%016"PRIx64
, volset_nr
);
346 if (context
.fileset_name
== NULL
)
347 context
.fileset_name
= strdup("anonymous");
349 /* check passed/created identifiers */
350 if (strlen(context
.logvol_name
) > 128) {
351 (void)printf("Logical volume name too long\n");
354 if (strlen(context
.primary_name
) > 32) {
355 (void)printf("Primary volume name too long\n");
358 if (strlen(context
.volset_name
) > 128) {
359 (void)printf("Volume set name too long\n");
362 if (strlen(context
.fileset_name
) > 32) {
363 (void)printf("Fileset name too long\n");
371 /* --------------------------------------------------------------------- */
374 udf_write_iso9660_vrs(void)
376 struct vrs_desc
*iso9660_vrs_desc
;
378 int error
, cnt
, dpos
;
380 /* create ISO/Ecma-167 identification descriptors */
381 if ((iso9660_vrs_desc
= calloc(1, context
.sector_size
)) == NULL
)
385 * All UDF formats should have their ISO/Ecma-167 descriptors written
386 * except when not possible due to track reservation in the case of
389 if ((format_flags
& FORMAT_TRACK512
) == 0) {
390 dpos
= (2048 + context
.sector_size
- 1) / context
.sector_size
;
392 /* wipe at least 6 times 2048 byte `sectors' */
393 for (cnt
= 0; cnt
< 6 *dpos
; cnt
++) {
394 pos
= layout
.iso9660_vrs
+ cnt
;
395 if ((error
= udf_write_sector(iso9660_vrs_desc
, pos
))) {
396 free(iso9660_vrs_desc
);
401 /* common VRS fields in all written out ISO descriptors */
402 iso9660_vrs_desc
->struct_type
= 0;
403 iso9660_vrs_desc
->version
= 1;
404 pos
= layout
.iso9660_vrs
;
406 /* BEA01, NSR[23], TEA01 */
407 memcpy(iso9660_vrs_desc
->identifier
, "BEA01", 5);
408 if ((error
= udf_write_sector(iso9660_vrs_desc
, pos
))) {
409 free(iso9660_vrs_desc
);
414 if (context
.dscrver
== 2)
415 memcpy(iso9660_vrs_desc
->identifier
, "NSR02", 5);
417 memcpy(iso9660_vrs_desc
->identifier
, "NSR03", 5);
419 if ((error
= udf_write_sector(iso9660_vrs_desc
, pos
))) {
420 free(iso9660_vrs_desc
);
425 memcpy(iso9660_vrs_desc
->identifier
, "TEA01", 5);
426 if ((error
= udf_write_sector(iso9660_vrs_desc
, pos
))) {
427 free(iso9660_vrs_desc
);
432 free(iso9660_vrs_desc
);
438 /* --------------------------------------------------------------------- */
441 * Main function that creates and writes out disc contents based on the
442 * format_flags's that uniquely define the type of disc to create.
446 udf_do_newfs_prefix(void)
448 union dscrptr
*zero_dscr
;
450 struct mmc_trackinfo ti
;
451 uint32_t sparable_blocks
;
452 uint32_t sector_size
, blockingnr
;
453 uint32_t cnt
, loc
, len
;
455 int error
, integrity_type
;
456 int data_part
, metadata_part
;
459 sector_size
= mmc_discinfo
.sector_size
;
461 /* determine span/size */
462 ti
.tracknr
= mmc_discinfo
.first_track_last_session
;
463 error
= udf_update_trackinfo(&mmc_discinfo
, &ti
);
467 if (mmc_discinfo
.sector_size
< context
.sector_size
) {
468 fprintf(stderr
, "Impossible to format: sectorsize too small\n");
471 context
.sector_size
= sector_size
;
473 /* determine blockingnr */
474 blockingnr
= ti
.packet_size
;
475 if (blockingnr
<= 1) {
476 /* paranoia on blockingnr */
477 switch (mmc_discinfo
.mmc_profile
) {
478 case 0x08 : /* CDROM */
479 case 0x09 : /* CD-R */
480 case 0x0a : /* CD-RW */
481 blockingnr
= 32; /* UDF requirement */
483 case 0x10 : /* DVDROM */
484 case 0x11 : /* DVD-R (DL) */
485 case 0x12 : /* DVD-RAM */
486 case 0x1b : /* DVD+R */
487 case 0x2b : /* DVD+R Dual layer */
488 case 0x13 : /* DVD-RW restricted overwrite */
489 case 0x14 : /* DVD-RW sequential */
490 blockingnr
= 16; /* SCSI definition */
492 case 0x40 : /* BDROM */
493 case 0x41 : /* BD-R Sequential recording (SRM) */
494 case 0x42 : /* BD-R Random recording (RRM) */
495 case 0x43 : /* BD-RE */
496 case 0x51 : /* HD DVD-R */
497 case 0x52 : /* HD DVD-RW */
498 blockingnr
= 32; /* SCSI definition */
504 if (blockingnr
<= 0) {
505 printf("Can't fixup blockingnumber for device "
506 "type %d\n", mmc_discinfo
.mmc_profile
);
508 printf("Device is not returning valid blocking"
509 " number and media type is unknown.\n");
513 wrtrack_skew
= ti
.track_start
% blockingnr
;
515 if (mmc_discinfo
.mmc_class
== MMC_CLASS_CD
) {
516 /* not too much for CD-RW, still 20MiB */
517 sparable_blocks
= 32;
519 /* take a value for DVD*RW mainly, BD is `defect free' */
520 sparable_blocks
= 512;
524 error
= udf_calculate_disc_layout(format_flags
, context
.min_udf
,
526 ti
.track_start
, mmc_discinfo
.last_possible_lba
,
527 context
.sector_size
, blockingnr
, sparable_blocks
,
530 /* cache partition for we need it often */
531 data_part
= context
.data_part
;
532 metadata_part
= context
.metadata_part
;
534 /* Create sparing table descriptor if applicable */
535 if (format_flags
& FORMAT_SPARABLE
) {
536 if ((error
= udf_create_sparing_tabled()))
540 if ((error
= udf_surface_check()))
545 /* Create a generic terminator descriptor (later reused) */
546 terminator_dscr
= calloc(1, sector_size
);
547 if (terminator_dscr
== NULL
)
549 udf_create_terminator(terminator_dscr
, 0);
552 * Start with wipeout of VRS1 upto start of partition. This allows
553 * formatting for sequentials with the track reservation and it
554 * cleans old rubbish on rewritables. For sequentuals without the
555 * track reservation all is wiped from track start.
557 if ((zero_dscr
= calloc(1, context
.sector_size
)) == NULL
)
560 loc
= (format_flags
& FORMAT_TRACK512
) ? layout
.vds1
: ti
.track_start
;
561 for (; loc
< layout
.part_start_lba
; loc
++) {
562 if ((error
= udf_write_sector(zero_dscr
, loc
))) {
570 for (cnt
= 0; cnt
< 3; cnt
++) {
571 if ((error
= udf_create_anchor(cnt
))) {
577 * Create the two Volume Descriptor Sets (VDS) each containing the
578 * following descriptors : primary volume, partition space,
579 * unallocated space, logical volume, implementation use and the
583 /* start of volume recognision sequence building */
586 /* Create primary volume descriptor */
587 if ((error
= udf_create_primaryd()))
590 /* Create partition descriptor */
591 if ((error
= udf_create_partitiond(context
.data_part
, media_accesstype
)))
594 /* Create unallocated space descriptor */
595 if ((error
= udf_create_unalloc_spaced()))
598 /* Create logical volume descriptor */
599 if ((error
= udf_create_logical_dscr(format_flags
)))
602 /* Create implementation use descriptor */
603 /* TODO input of fields 1,2,3 and passing them */
604 if ((error
= udf_create_impvold(NULL
, NULL
, NULL
)))
607 /* write out what we've created so far */
609 /* writeout iso9660 vrs */
610 if ((error
= udf_write_iso9660_vrs()))
613 /* Writeout anchors */
614 for (cnt
= 0; cnt
< 3; cnt
++) {
615 dscr
= (union dscrptr
*) context
.anchors
[cnt
];
616 loc
= layout
.anchors
[cnt
];
617 if ((error
= udf_write_dscr_phys(dscr
, loc
, 1)))
620 /* sequential media has only one anchor */
621 if (format_flags
& FORMAT_SEQUENTIAL
)
625 /* write out main and secondary VRS */
626 for (sectcopy
= 1; sectcopy
<= 2; sectcopy
++) {
627 loc
= (sectcopy
== 1) ? layout
.vds1
: layout
.vds2
;
629 /* primary volume descriptor */
630 dscr
= (union dscrptr
*) context
.primary_vol
;
631 error
= udf_write_dscr_phys(dscr
, loc
, 1);
636 /* partition descriptor(s) */
637 for (cnt
= 0; cnt
< UDF_PARTITIONS
; cnt
++) {
638 dscr
= (union dscrptr
*) context
.partitions
[cnt
];
640 error
= udf_write_dscr_phys(dscr
, loc
, 1);
647 /* unallocated space descriptor */
648 dscr
= (union dscrptr
*) context
.unallocated
;
649 error
= udf_write_dscr_phys(dscr
, loc
, 1);
654 /* logical volume descriptor */
655 dscr
= (union dscrptr
*) context
.logical_vol
;
656 error
= udf_write_dscr_phys(dscr
, loc
, 1);
661 /* implementation use descriptor */
662 dscr
= (union dscrptr
*) context
.implementation
;
663 error
= udf_write_dscr_phys(dscr
, loc
, 1);
668 /* terminator descriptor */
669 error
= udf_write_dscr_phys(terminator_dscr
, loc
, 1);
675 /* writeout the two sparable table descriptors (if needed) */
676 if (format_flags
& FORMAT_SPARABLE
) {
677 for (sectcopy
= 1; sectcopy
<= 2; sectcopy
++) {
678 loc
= (sectcopy
== 1) ? layout
.spt_1
: layout
.spt_2
;
679 dscr
= (union dscrptr
*) context
.sparing_table
;
680 len
= layout
.sparing_table_dscr_lbas
;
683 error
= udf_write_dscr_phys(dscr
, loc
, len
);
690 * Create unallocated space bitmap descriptor. Sequential recorded
691 * media report their own free/used space; no free/used space tables
692 * should be recorded for these.
694 if ((format_flags
& (FORMAT_SEQUENTIAL
| FORMAT_READONLY
)) == 0) {
695 error
= udf_create_space_bitmap(
696 layout
.alloc_bitmap_dscr_size
,
697 layout
.part_size_lba
,
698 &context
.part_unalloc_bits
[data_part
]);
701 /* TODO: freed space bitmap if applicable */
703 /* mark space allocated for the unallocated space bitmap */
704 udf_mark_allocated(layout
.unalloc_space
, data_part
,
705 layout
.alloc_bitmap_dscr_size
);
709 * Create metadata partition file entries and allocate and init their
710 * space and free space maps.
712 if (format_flags
& FORMAT_META
) {
713 error
= udf_create_space_bitmap(
714 layout
.meta_bitmap_dscr_size
,
715 layout
.meta_part_size_lba
,
716 &context
.part_unalloc_bits
[metadata_part
]);
720 error
= udf_create_meta_files();
724 /* mark space allocated for meta partition and its bitmap */
725 udf_mark_allocated(layout
.meta_file
, data_part
, 1);
726 udf_mark_allocated(layout
.meta_mirror
, data_part
, 1);
727 udf_mark_allocated(layout
.meta_bitmap
, data_part
, 1);
728 udf_mark_allocated(layout
.meta_part_start_lba
, data_part
,
729 layout
.meta_part_size_lba
);
731 /* mark space allocated for the unallocated space bitmap */
732 udf_mark_allocated(layout
.meta_bitmap_space
, data_part
,
733 layout
.meta_bitmap_dscr_size
);
736 /* create logical volume integrity descriptor */
737 context
.num_files
= 0;
738 context
.num_directories
= 0;
739 integrity_type
= UDF_INTEGRITY_OPEN
;
740 if ((error
= udf_create_lvintd(integrity_type
)))
743 /* writeout initial open integrity sequence + terminator */
745 dscr
= (union dscrptr
*) context
.logvol_integrity
;
746 error
= udf_write_dscr_phys(dscr
, loc
, 1);
750 error
= udf_write_dscr_phys(terminator_dscr
, loc
, 1);
754 /* create VAT if needed */
755 if (format_flags
& FORMAT_VAT
) {
756 context
.vat_allocated
= context
.sector_size
;
757 context
.vat_contents
= malloc(context
.vat_allocated
);
758 assert(context
.vat_contents
);
760 udf_prepend_VAT_file();
763 /* create FSD and writeout */
764 if ((error
= udf_create_fsd()))
766 udf_mark_allocated(layout
.fsd
, metadata_part
, 1);
768 dscr
= (union dscrptr
*) context
.fileset_desc
;
769 error
= udf_write_dscr_virt(dscr
, layout
.fsd
, metadata_part
, 1);
775 /* specific routine for newfs to create empty rootdirectory */
777 udf_do_rootdir(void) {
778 union dscrptr
*root_dscr
;
781 /* create root directory and write out */
782 assert(context
.unique_id
== 0x10);
783 context
.unique_id
= 0;
784 if ((error
= udf_create_new_rootdir(&root_dscr
)))
786 udf_mark_allocated(layout
.rootdir
, context
.metadata_part
, 1);
788 error
= udf_write_dscr_virt(root_dscr
,
789 layout
.rootdir
, context
.metadata_part
, 1);
798 udf_do_newfs_postfix(void)
800 union dscrptr
*vat_dscr
;
802 struct long_ad vatdata_pos
;
803 uint32_t loc
, len
, phys
, sects
;
804 int data_part
, metadata_part
;
807 /* cache partition for we need it often */
808 data_part
= context
.data_part
;
809 metadata_part
= context
.metadata_part
;
811 if ((format_flags
& FORMAT_SEQUENTIAL
) == 0) {
812 /* update lvint and mark it closed */
813 udf_update_lvintd(UDF_INTEGRITY_CLOSED
);
815 /* overwrite initial terminator */
817 dscr
= (union dscrptr
*) context
.logvol_integrity
;
818 error
= udf_write_dscr_phys(dscr
, loc
, 1);
823 /* mark end of integrity desciptor sequence again */
824 error
= udf_write_dscr_phys(terminator_dscr
, loc
, 1);
829 /* write out unallocated space bitmap on non sequential media */
830 if ((format_flags
& (FORMAT_SEQUENTIAL
| FORMAT_READONLY
)) == 0) {
831 /* writeout unallocated space bitmap */
832 loc
= layout
.unalloc_space
;
833 dscr
= (union dscrptr
*) (context
.part_unalloc_bits
[data_part
]);
834 len
= layout
.alloc_bitmap_dscr_size
;
835 error
= udf_write_dscr_virt(dscr
, loc
, data_part
, len
);
840 if (format_flags
& FORMAT_META
) {
841 loc
= layout
.meta_file
;
842 dscr
= (union dscrptr
*) context
.meta_file
;
843 error
= udf_write_dscr_virt(dscr
, loc
, data_part
, 1);
847 loc
= layout
.meta_mirror
;
848 dscr
= (union dscrptr
*) context
.meta_mirror
;
849 error
= udf_write_dscr_virt(dscr
, loc
, data_part
, 1);
853 loc
= layout
.meta_bitmap
;
854 dscr
= (union dscrptr
*) context
.meta_bitmap
;
855 error
= udf_write_dscr_virt(dscr
, loc
, data_part
, 1);
859 /* writeout unallocated space bitmap */
860 loc
= layout
.meta_bitmap_space
;
861 dscr
= (union dscrptr
*)
862 (context
.part_unalloc_bits
[metadata_part
]);
863 len
= layout
.meta_bitmap_dscr_size
;
864 error
= udf_write_dscr_virt(dscr
, loc
, data_part
, len
);
869 /* create a VAT and account for FSD+root */
871 if (format_flags
& FORMAT_VAT
) {
872 /* update lvint to reflect the newest values (no writeout) */
873 udf_update_lvintd(UDF_INTEGRITY_CLOSED
);
875 error
= udf_append_VAT_file();
879 /* write out VAT data */
880 sects
= UDF_ROUNDUP(context
.vat_size
, context
.sector_size
) /
882 layout
.vat
= context
.data_alloc_pos
;
883 udf_data_alloc(sects
, &vatdata_pos
);
885 loc
= udf_rw32(vatdata_pos
.loc
.lb_num
);
886 phys
= context
.vtop_offset
[context
.data_part
] + loc
;
888 error
= udf_write_phys(context
.vat_contents
, phys
, sects
);
893 /* create new VAT descriptor */
894 error
= udf_create_VAT(&vat_dscr
);
897 context
.data_alloc_pos
++;
900 error
= udf_write_dscr_virt(vat_dscr
, loc
, metadata_part
, 1);