1*0a6a1f1dSLionel Sambuc /* $NetBSD: udf_write.c,v 1.9 2015/01/02 21:01:12 reinoud Exp $ */
29f988b79SJean-Baptiste Boric
39f988b79SJean-Baptiste Boric /*
49f988b79SJean-Baptiste Boric * Copyright (c) 2006, 2008, 2013 Reinoud Zandijk
59f988b79SJean-Baptiste Boric * All rights reserved.
69f988b79SJean-Baptiste Boric *
79f988b79SJean-Baptiste Boric * Redistribution and use in source and binary forms, with or without
89f988b79SJean-Baptiste Boric * modification, are permitted provided that the following conditions
99f988b79SJean-Baptiste Boric * are met:
109f988b79SJean-Baptiste Boric * 1. Redistributions of source code must retain the above copyright
119f988b79SJean-Baptiste Boric * notice, this list of conditions and the following disclaimer.
129f988b79SJean-Baptiste Boric * 2. Redistributions in binary form must reproduce the above copyright
139f988b79SJean-Baptiste Boric * notice, this list of conditions and the following disclaimer in the
149f988b79SJean-Baptiste Boric * documentation and/or other materials provided with the distribution.
159f988b79SJean-Baptiste Boric *
169f988b79SJean-Baptiste Boric * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
179f988b79SJean-Baptiste Boric * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
189f988b79SJean-Baptiste Boric * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
199f988b79SJean-Baptiste Boric * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
209f988b79SJean-Baptiste Boric * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
219f988b79SJean-Baptiste Boric * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
229f988b79SJean-Baptiste Boric * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
239f988b79SJean-Baptiste Boric * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
249f988b79SJean-Baptiste Boric * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
259f988b79SJean-Baptiste Boric * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
269f988b79SJean-Baptiste Boric *
279f988b79SJean-Baptiste Boric */
289f988b79SJean-Baptiste Boric #if HAVE_NBTOOL_CONFIG_H
299f988b79SJean-Baptiste Boric #include "nbtool_config.h"
309f988b79SJean-Baptiste Boric #endif
319f988b79SJean-Baptiste Boric
329f988b79SJean-Baptiste Boric #include <sys/cdefs.h>
33*0a6a1f1dSLionel Sambuc __RCSID("$NetBSD: udf_write.c,v 1.9 2015/01/02 21:01:12 reinoud Exp $");
349f988b79SJean-Baptiste Boric
359f988b79SJean-Baptiste Boric #include <stdio.h>
369f988b79SJean-Baptiste Boric #include <stdlib.h>
379f988b79SJean-Baptiste Boric #include <string.h>
389f988b79SJean-Baptiste Boric #include <errno.h>
399f988b79SJean-Baptiste Boric #include <time.h>
409f988b79SJean-Baptiste Boric #include <assert.h>
419f988b79SJean-Baptiste Boric #include <err.h>
429f988b79SJean-Baptiste Boric #include <sys/types.h>
439f988b79SJean-Baptiste Boric #include <sys/param.h>
449f988b79SJean-Baptiste Boric
459f988b79SJean-Baptiste Boric #if !HAVE_NBTOOL_CONFIG_H
469f988b79SJean-Baptiste Boric #define _EXPOSE_MMC
479f988b79SJean-Baptiste Boric #include <sys/cdio.h>
489f988b79SJean-Baptiste Boric #else
499f988b79SJean-Baptiste Boric #include "udf/cdio_mmc_structs.h"
509f988b79SJean-Baptiste Boric #endif
519f988b79SJean-Baptiste Boric
529f988b79SJean-Baptiste Boric #include "udf_create.h"
539f988b79SJean-Baptiste Boric #include "udf_write.h"
549f988b79SJean-Baptiste Boric #include "newfs_udf.h"
559f988b79SJean-Baptiste Boric
569f988b79SJean-Baptiste Boric
579f988b79SJean-Baptiste Boric union dscrptr *terminator_dscr;
589f988b79SJean-Baptiste Boric
599f988b79SJean-Baptiste Boric static int
udf_write_phys(void * blob,uint32_t location,uint32_t sects)609f988b79SJean-Baptiste Boric udf_write_phys(void *blob, uint32_t location, uint32_t sects)
619f988b79SJean-Baptiste Boric {
629f988b79SJean-Baptiste Boric uint32_t phys, cnt;
639f988b79SJean-Baptiste Boric uint8_t *bpos;
649f988b79SJean-Baptiste Boric int error;
659f988b79SJean-Baptiste Boric
669f988b79SJean-Baptiste Boric for (cnt = 0; cnt < sects; cnt++) {
679f988b79SJean-Baptiste Boric bpos = (uint8_t *) blob;
689f988b79SJean-Baptiste Boric bpos += context.sector_size * cnt;
699f988b79SJean-Baptiste Boric
709f988b79SJean-Baptiste Boric phys = location + cnt;
719f988b79SJean-Baptiste Boric error = udf_write_sector(bpos, phys);
729f988b79SJean-Baptiste Boric if (error)
739f988b79SJean-Baptiste Boric return error;
749f988b79SJean-Baptiste Boric }
759f988b79SJean-Baptiste Boric return 0;
769f988b79SJean-Baptiste Boric }
779f988b79SJean-Baptiste Boric
789f988b79SJean-Baptiste Boric
799f988b79SJean-Baptiste Boric static int
udf_write_dscr_phys(union dscrptr * dscr,uint32_t location,uint32_t sects)809f988b79SJean-Baptiste Boric udf_write_dscr_phys(union dscrptr *dscr, uint32_t location,
819f988b79SJean-Baptiste Boric uint32_t sects)
829f988b79SJean-Baptiste Boric {
839f988b79SJean-Baptiste Boric dscr->tag.tag_loc = udf_rw32(location);
849f988b79SJean-Baptiste Boric (void) udf_validate_tag_and_crc_sums(dscr);
859f988b79SJean-Baptiste Boric
869f988b79SJean-Baptiste Boric return udf_write_phys(dscr, location, sects);
879f988b79SJean-Baptiste Boric }
889f988b79SJean-Baptiste Boric
899f988b79SJean-Baptiste Boric
909f988b79SJean-Baptiste Boric int
udf_write_dscr_virt(union dscrptr * dscr,uint32_t location,uint32_t vpart,uint32_t sects)919f988b79SJean-Baptiste Boric udf_write_dscr_virt(union dscrptr *dscr, uint32_t location, uint32_t vpart,
929f988b79SJean-Baptiste Boric uint32_t sects)
939f988b79SJean-Baptiste Boric {
949f988b79SJean-Baptiste Boric struct file_entry *fe;
959f988b79SJean-Baptiste Boric struct extfile_entry *efe;
969f988b79SJean-Baptiste Boric struct extattrhdr_desc *extattrhdr;
979f988b79SJean-Baptiste Boric uint32_t phys;
989f988b79SJean-Baptiste Boric
999f988b79SJean-Baptiste Boric extattrhdr = NULL;
1009f988b79SJean-Baptiste Boric if (udf_rw16(dscr->tag.id) == TAGID_FENTRY) {
1019f988b79SJean-Baptiste Boric fe = (struct file_entry *) dscr;
1029f988b79SJean-Baptiste Boric if (udf_rw32(fe->l_ea) > 0)
1039f988b79SJean-Baptiste Boric extattrhdr = (struct extattrhdr_desc *) fe->data;
1049f988b79SJean-Baptiste Boric }
1059f988b79SJean-Baptiste Boric if (udf_rw16(dscr->tag.id) == TAGID_EXTFENTRY) {
1069f988b79SJean-Baptiste Boric efe = (struct extfile_entry *) dscr;
1079f988b79SJean-Baptiste Boric if (udf_rw32(efe->l_ea) > 0)
1089f988b79SJean-Baptiste Boric extattrhdr = (struct extattrhdr_desc *) efe->data;
1099f988b79SJean-Baptiste Boric }
1109f988b79SJean-Baptiste Boric if (extattrhdr) {
1119f988b79SJean-Baptiste Boric extattrhdr->tag.tag_loc = udf_rw32(location);
1129f988b79SJean-Baptiste Boric udf_validate_tag_and_crc_sums((union dscrptr *) extattrhdr);
1139f988b79SJean-Baptiste Boric }
1149f988b79SJean-Baptiste Boric
1159f988b79SJean-Baptiste Boric dscr->tag.tag_loc = udf_rw32(location);
1169f988b79SJean-Baptiste Boric udf_validate_tag_and_crc_sums(dscr);
1179f988b79SJean-Baptiste Boric
1189f988b79SJean-Baptiste Boric /* determine physical location */
1199f988b79SJean-Baptiste Boric phys = context.vtop_offset[vpart];
1209f988b79SJean-Baptiste Boric if (context.vtop_tp[vpart] == UDF_VTOP_TYPE_VIRT) {
1219f988b79SJean-Baptiste Boric udf_vat_update(location, context.data_alloc_pos);
1229f988b79SJean-Baptiste Boric phys += context.data_alloc_pos++;
1239f988b79SJean-Baptiste Boric } else {
1249f988b79SJean-Baptiste Boric phys += location;
1259f988b79SJean-Baptiste Boric }
1269f988b79SJean-Baptiste Boric
1279f988b79SJean-Baptiste Boric return udf_write_phys(dscr, phys, sects);
1289f988b79SJean-Baptiste Boric }
1299f988b79SJean-Baptiste Boric
1309f988b79SJean-Baptiste Boric
1319f988b79SJean-Baptiste Boric void
udf_metadata_alloc(int nblk,struct long_ad * pos)1329f988b79SJean-Baptiste Boric udf_metadata_alloc(int nblk, struct long_ad *pos)
1339f988b79SJean-Baptiste Boric {
1349f988b79SJean-Baptiste Boric memset(pos, 0, sizeof(*pos));
1359f988b79SJean-Baptiste Boric pos->len = udf_rw32(nblk * context.sector_size);
1369f988b79SJean-Baptiste Boric pos->loc.lb_num = udf_rw32(context.metadata_alloc_pos);
1379f988b79SJean-Baptiste Boric pos->loc.part_num = udf_rw16(context.metadata_part);
1389f988b79SJean-Baptiste Boric
1399f988b79SJean-Baptiste Boric udf_mark_allocated(context.metadata_alloc_pos, context.metadata_part,
1409f988b79SJean-Baptiste Boric nblk);
1419f988b79SJean-Baptiste Boric
1429f988b79SJean-Baptiste Boric context.metadata_alloc_pos += nblk;
1439f988b79SJean-Baptiste Boric if (context.metadata_part == context.data_part)
1449f988b79SJean-Baptiste Boric context.data_alloc_pos = context.metadata_alloc_pos;
1459f988b79SJean-Baptiste Boric }
1469f988b79SJean-Baptiste Boric
1479f988b79SJean-Baptiste Boric
1489f988b79SJean-Baptiste Boric void
udf_data_alloc(int nblk,struct long_ad * pos)1499f988b79SJean-Baptiste Boric udf_data_alloc(int nblk, struct long_ad *pos)
1509f988b79SJean-Baptiste Boric {
1519f988b79SJean-Baptiste Boric memset(pos, 0, sizeof(*pos));
1529f988b79SJean-Baptiste Boric pos->len = udf_rw32(nblk * context.sector_size);
1539f988b79SJean-Baptiste Boric pos->loc.lb_num = udf_rw32(context.data_alloc_pos);
1549f988b79SJean-Baptiste Boric pos->loc.part_num = udf_rw16(context.data_part);
1559f988b79SJean-Baptiste Boric
1569f988b79SJean-Baptiste Boric udf_mark_allocated(context.data_alloc_pos, context.data_part, nblk);
1579f988b79SJean-Baptiste Boric context.data_alloc_pos += nblk;
1589f988b79SJean-Baptiste Boric if (context.metadata_part == context.data_part)
1599f988b79SJean-Baptiste Boric context.metadata_alloc_pos = context.data_alloc_pos;
1609f988b79SJean-Baptiste Boric }
1619f988b79SJean-Baptiste Boric
1629f988b79SJean-Baptiste Boric
1639f988b79SJean-Baptiste Boric
1649f988b79SJean-Baptiste Boric /* --------------------------------------------------------------------- */
1659f988b79SJean-Baptiste Boric
1669f988b79SJean-Baptiste Boric /*
1679f988b79SJean-Baptiste Boric * udf_derive_format derives the format_flags from the disc's mmc_discinfo.
1689f988b79SJean-Baptiste Boric * The resulting flags uniquely define a disc format. Note there are at least
1699f988b79SJean-Baptiste Boric * 7 distinct format types defined in UDF.
1709f988b79SJean-Baptiste Boric */
1719f988b79SJean-Baptiste Boric
1729f988b79SJean-Baptiste Boric #define UDF_VERSION(a) \
1739f988b79SJean-Baptiste Boric (((a) == 0x100) || ((a) == 0x102) || ((a) == 0x150) || ((a) == 0x200) || \
1749f988b79SJean-Baptiste Boric ((a) == 0x201) || ((a) == 0x250) || ((a) == 0x260))
1759f988b79SJean-Baptiste Boric
1769f988b79SJean-Baptiste Boric int
udf_derive_format(int req_enable,int req_disable,int force)1779f988b79SJean-Baptiste Boric udf_derive_format(int req_enable, int req_disable, int force)
1789f988b79SJean-Baptiste Boric {
1799f988b79SJean-Baptiste Boric /* disc writability, formatted, appendable */
1809f988b79SJean-Baptiste Boric if ((mmc_discinfo.mmc_cur & MMC_CAP_RECORDABLE) == 0) {
1819f988b79SJean-Baptiste Boric (void)printf("Can't newfs readonly device\n");
1829f988b79SJean-Baptiste Boric return EROFS;
1839f988b79SJean-Baptiste Boric }
1849f988b79SJean-Baptiste Boric if (mmc_discinfo.mmc_cur & MMC_CAP_SEQUENTIAL) {
1859f988b79SJean-Baptiste Boric /* sequentials need sessions appended */
1869f988b79SJean-Baptiste Boric if (mmc_discinfo.disc_state == MMC_STATE_CLOSED) {
1879f988b79SJean-Baptiste Boric (void)printf("Can't append session to a closed disc\n");
1889f988b79SJean-Baptiste Boric return EROFS;
1899f988b79SJean-Baptiste Boric }
1909f988b79SJean-Baptiste Boric if ((mmc_discinfo.disc_state != MMC_STATE_EMPTY) && !force) {
1919f988b79SJean-Baptiste Boric (void)printf("Disc not empty! Use -F to force "
1929f988b79SJean-Baptiste Boric "initialisation\n");
1939f988b79SJean-Baptiste Boric return EROFS;
1949f988b79SJean-Baptiste Boric }
1959f988b79SJean-Baptiste Boric } else {
1969f988b79SJean-Baptiste Boric /* check if disc (being) formatted or has been started on */
1979f988b79SJean-Baptiste Boric if (mmc_discinfo.disc_state == MMC_STATE_EMPTY) {
1989f988b79SJean-Baptiste Boric (void)printf("Disc is not formatted\n");
1999f988b79SJean-Baptiste Boric return EROFS;
2009f988b79SJean-Baptiste Boric }
2019f988b79SJean-Baptiste Boric }
2029f988b79SJean-Baptiste Boric
2039f988b79SJean-Baptiste Boric /* determine UDF format */
2049f988b79SJean-Baptiste Boric format_flags = 0;
2059f988b79SJean-Baptiste Boric if (mmc_discinfo.mmc_cur & MMC_CAP_REWRITABLE) {
2069f988b79SJean-Baptiste Boric /* all rewritable media */
2079f988b79SJean-Baptiste Boric format_flags |= FORMAT_REWRITABLE;
2089f988b79SJean-Baptiste Boric if (context.min_udf >= 0x0250) {
2099f988b79SJean-Baptiste Boric /* standard dictates meta as default */
2109f988b79SJean-Baptiste Boric format_flags |= FORMAT_META;
2119f988b79SJean-Baptiste Boric }
2129f988b79SJean-Baptiste Boric
2139f988b79SJean-Baptiste Boric if ((mmc_discinfo.mmc_cur & MMC_CAP_HW_DEFECTFREE) == 0) {
2149f988b79SJean-Baptiste Boric /* sparables for defect management */
2159f988b79SJean-Baptiste Boric if (context.min_udf >= 0x150)
2169f988b79SJean-Baptiste Boric format_flags |= FORMAT_SPARABLE;
2179f988b79SJean-Baptiste Boric }
2189f988b79SJean-Baptiste Boric } else {
2199f988b79SJean-Baptiste Boric /* all once recordable media */
2209f988b79SJean-Baptiste Boric format_flags |= FORMAT_WRITEONCE;
2219f988b79SJean-Baptiste Boric if (mmc_discinfo.mmc_cur & MMC_CAP_SEQUENTIAL) {
2229f988b79SJean-Baptiste Boric format_flags |= FORMAT_SEQUENTIAL;
2239f988b79SJean-Baptiste Boric
2249f988b79SJean-Baptiste Boric if (mmc_discinfo.mmc_cur & MMC_CAP_PSEUDOOVERWRITE) {
2259f988b79SJean-Baptiste Boric /* logical overwritable */
2269f988b79SJean-Baptiste Boric format_flags |= FORMAT_LOW;
2279f988b79SJean-Baptiste Boric } else {
2289f988b79SJean-Baptiste Boric /* have to use VAT for overwriting */
2299f988b79SJean-Baptiste Boric format_flags |= FORMAT_VAT;
2309f988b79SJean-Baptiste Boric }
2319f988b79SJean-Baptiste Boric } else {
2329f988b79SJean-Baptiste Boric /* rare WORM devices, but BluRay has one, strat4096 */
2339f988b79SJean-Baptiste Boric format_flags |= FORMAT_WORM;
2349f988b79SJean-Baptiste Boric }
2359f988b79SJean-Baptiste Boric }
2369f988b79SJean-Baptiste Boric
2379f988b79SJean-Baptiste Boric /* enable/disable requests */
2389f988b79SJean-Baptiste Boric if (req_disable & FORMAT_META) {
2399f988b79SJean-Baptiste Boric format_flags &= ~(FORMAT_META | FORMAT_LOW);
2409f988b79SJean-Baptiste Boric req_disable &= ~FORMAT_META;
2419f988b79SJean-Baptiste Boric }
2429f988b79SJean-Baptiste Boric if ((format_flags & FORMAT_VAT) & UDF_512_TRACK)
2439f988b79SJean-Baptiste Boric format_flags |= FORMAT_TRACK512;
2449f988b79SJean-Baptiste Boric
2459f988b79SJean-Baptiste Boric if (req_enable & FORMAT_READONLY) {
2469f988b79SJean-Baptiste Boric format_flags |= FORMAT_READONLY;
2479f988b79SJean-Baptiste Boric }
2489f988b79SJean-Baptiste Boric
2499f988b79SJean-Baptiste Boric /* determine partition/media access type */
2509f988b79SJean-Baptiste Boric media_accesstype = UDF_ACCESSTYPE_NOT_SPECIFIED;
2519f988b79SJean-Baptiste Boric if (mmc_discinfo.mmc_cur & MMC_CAP_REWRITABLE) {
2529f988b79SJean-Baptiste Boric media_accesstype = UDF_ACCESSTYPE_OVERWRITABLE;
2539f988b79SJean-Baptiste Boric if (mmc_discinfo.mmc_cur & MMC_CAP_ERASABLE)
2549f988b79SJean-Baptiste Boric media_accesstype = UDF_ACCESSTYPE_REWRITEABLE;
2559f988b79SJean-Baptiste Boric } else {
2569f988b79SJean-Baptiste Boric /* all once recordable media */
2579f988b79SJean-Baptiste Boric media_accesstype = UDF_ACCESSTYPE_WRITE_ONCE;
2589f988b79SJean-Baptiste Boric }
2599f988b79SJean-Baptiste Boric if (mmc_discinfo.mmc_cur & MMC_CAP_PSEUDOOVERWRITE)
2609f988b79SJean-Baptiste Boric media_accesstype = UDF_ACCESSTYPE_PSEUDO_OVERWITE;
2619f988b79SJean-Baptiste Boric
2629f988b79SJean-Baptiste Boric /* patch up media accesstype */
2639f988b79SJean-Baptiste Boric if (req_enable & FORMAT_READONLY) {
2649f988b79SJean-Baptiste Boric /* better now */
2659f988b79SJean-Baptiste Boric media_accesstype = UDF_ACCESSTYPE_READ_ONLY;
2669f988b79SJean-Baptiste Boric }
2679f988b79SJean-Baptiste Boric
2689f988b79SJean-Baptiste Boric /* adjust minimum version limits */
2699f988b79SJean-Baptiste Boric if (format_flags & FORMAT_VAT)
2709f988b79SJean-Baptiste Boric context.min_udf = MAX(context.min_udf, 0x0150);
2719f988b79SJean-Baptiste Boric if (format_flags & FORMAT_SPARABLE)
2729f988b79SJean-Baptiste Boric context.min_udf = MAX(context.min_udf, 0x0150);
2739f988b79SJean-Baptiste Boric if (format_flags & FORMAT_META)
2749f988b79SJean-Baptiste Boric context.min_udf = MAX(context.min_udf, 0x0250);
2759f988b79SJean-Baptiste Boric if (format_flags & FORMAT_LOW)
2769f988b79SJean-Baptiste Boric context.min_udf = MAX(context.min_udf, 0x0260);
2779f988b79SJean-Baptiste Boric
2789f988b79SJean-Baptiste Boric /* adjust maximum version limits not to tease or break things */
2799f988b79SJean-Baptiste Boric if (!(format_flags & (FORMAT_META | FORMAT_LOW)) &&
2809f988b79SJean-Baptiste Boric (context.max_udf > 0x200))
2819f988b79SJean-Baptiste Boric context.max_udf = 0x201;
2829f988b79SJean-Baptiste Boric
2839f988b79SJean-Baptiste Boric if ((format_flags & (FORMAT_VAT | FORMAT_SPARABLE)) == 0)
2849f988b79SJean-Baptiste Boric if (context.max_udf <= 0x150)
2859f988b79SJean-Baptiste Boric context.min_udf = 0x102;
2869f988b79SJean-Baptiste Boric
2879f988b79SJean-Baptiste Boric /* limit Ecma 167 descriptor if possible/needed */
2889f988b79SJean-Baptiste Boric context.dscrver = 3;
2899f988b79SJean-Baptiste Boric if ((context.min_udf < 0x200) || (context.max_udf < 0x200)) {
2909f988b79SJean-Baptiste Boric context.dscrver = 2;
2919f988b79SJean-Baptiste Boric context.max_udf = 0x150; /* last version < 0x200 */
2929f988b79SJean-Baptiste Boric }
2939f988b79SJean-Baptiste Boric
2949f988b79SJean-Baptiste Boric /* is it possible ? */
2959f988b79SJean-Baptiste Boric if (context.min_udf > context.max_udf) {
2969f988b79SJean-Baptiste Boric (void)printf("Initialisation prohibited by specified maximum "
2979f988b79SJean-Baptiste Boric "UDF version 0x%04x. Minimum version required 0x%04x\n",
2989f988b79SJean-Baptiste Boric context.max_udf, context.min_udf);
2999f988b79SJean-Baptiste Boric return EPERM;
3009f988b79SJean-Baptiste Boric }
3019f988b79SJean-Baptiste Boric
3029f988b79SJean-Baptiste Boric if (!UDF_VERSION(context.min_udf) || !UDF_VERSION(context.max_udf)) {
3039f988b79SJean-Baptiste Boric printf("Choose UDF version numbers from "
3049f988b79SJean-Baptiste Boric "0x102, 0x150, 0x200, 0x201, 0x250 and 0x260\n");
3059f988b79SJean-Baptiste Boric printf("Default version is 0x201\n");
3069f988b79SJean-Baptiste Boric return EPERM;
3079f988b79SJean-Baptiste Boric }
3089f988b79SJean-Baptiste Boric
3099f988b79SJean-Baptiste Boric return 0;
3109f988b79SJean-Baptiste Boric }
3119f988b79SJean-Baptiste Boric
3129f988b79SJean-Baptiste Boric #undef UDF_VERSION
3139f988b79SJean-Baptiste Boric
3149f988b79SJean-Baptiste Boric
3159f988b79SJean-Baptiste Boric /* --------------------------------------------------------------------- */
3169f988b79SJean-Baptiste Boric
3179f988b79SJean-Baptiste Boric int
udf_proces_names(void)3189f988b79SJean-Baptiste Boric udf_proces_names(void)
3199f988b79SJean-Baptiste Boric {
320*0a6a1f1dSLionel Sambuc struct timeval time_of_day;
3219f988b79SJean-Baptiste Boric uint32_t primary_nr;
3229f988b79SJean-Baptiste Boric uint64_t volset_nr;
3239f988b79SJean-Baptiste Boric
3249f988b79SJean-Baptiste Boric if (context.logvol_name == NULL)
3259f988b79SJean-Baptiste Boric context.logvol_name = strdup("anonymous");
3269f988b79SJean-Baptiste Boric if (context.primary_name == NULL) {
3279f988b79SJean-Baptiste Boric if (mmc_discinfo.disc_flags & MMC_DFLAGS_DISCIDVALID) {
3289f988b79SJean-Baptiste Boric primary_nr = mmc_discinfo.disc_id;
3299f988b79SJean-Baptiste Boric } else {
3309f988b79SJean-Baptiste Boric primary_nr = (uint32_t) random();
3319f988b79SJean-Baptiste Boric }
3329f988b79SJean-Baptiste Boric context.primary_name = calloc(32, 1);
3339f988b79SJean-Baptiste Boric sprintf(context.primary_name, "%08"PRIx32, primary_nr);
3349f988b79SJean-Baptiste Boric }
3359f988b79SJean-Baptiste Boric if (context.volset_name == NULL) {
3369f988b79SJean-Baptiste Boric if (mmc_discinfo.disc_flags & MMC_DFLAGS_BARCODEVALID) {
3379f988b79SJean-Baptiste Boric volset_nr = mmc_discinfo.disc_barcode;
3389f988b79SJean-Baptiste Boric } else {
339*0a6a1f1dSLionel Sambuc (void)gettimeofday(&time_of_day, NULL);
340*0a6a1f1dSLionel Sambuc volset_nr = (uint64_t) random();
341*0a6a1f1dSLionel Sambuc volset_nr |= ((uint64_t) time_of_day.tv_sec) << 32;
3429f988b79SJean-Baptiste Boric }
3439f988b79SJean-Baptiste Boric context.volset_name = calloc(128,1);
3449f988b79SJean-Baptiste Boric sprintf(context.volset_name, "%016"PRIx64, volset_nr);
3459f988b79SJean-Baptiste Boric }
3469f988b79SJean-Baptiste Boric if (context.fileset_name == NULL)
3479f988b79SJean-Baptiste Boric context.fileset_name = strdup("anonymous");
3489f988b79SJean-Baptiste Boric
3499f988b79SJean-Baptiste Boric /* check passed/created identifiers */
3509f988b79SJean-Baptiste Boric if (strlen(context.logvol_name) > 128) {
3519f988b79SJean-Baptiste Boric (void)printf("Logical volume name too long\n");
3529f988b79SJean-Baptiste Boric return EINVAL;
3539f988b79SJean-Baptiste Boric }
3549f988b79SJean-Baptiste Boric if (strlen(context.primary_name) > 32) {
3559f988b79SJean-Baptiste Boric (void)printf("Primary volume name too long\n");
3569f988b79SJean-Baptiste Boric return EINVAL;
3579f988b79SJean-Baptiste Boric }
3589f988b79SJean-Baptiste Boric if (strlen(context.volset_name) > 128) {
3599f988b79SJean-Baptiste Boric (void)printf("Volume set name too long\n");
3609f988b79SJean-Baptiste Boric return EINVAL;
3619f988b79SJean-Baptiste Boric }
3629f988b79SJean-Baptiste Boric if (strlen(context.fileset_name) > 32) {
3639f988b79SJean-Baptiste Boric (void)printf("Fileset name too long\n");
3649f988b79SJean-Baptiste Boric return EINVAL;
3659f988b79SJean-Baptiste Boric }
3669f988b79SJean-Baptiste Boric
3679f988b79SJean-Baptiste Boric /* signal all OK */
3689f988b79SJean-Baptiste Boric return 0;
3699f988b79SJean-Baptiste Boric }
3709f988b79SJean-Baptiste Boric
3719f988b79SJean-Baptiste Boric /* --------------------------------------------------------------------- */
3729f988b79SJean-Baptiste Boric
3739f988b79SJean-Baptiste Boric static int
udf_write_iso9660_vrs(void)3749f988b79SJean-Baptiste Boric udf_write_iso9660_vrs(void)
3759f988b79SJean-Baptiste Boric {
3769f988b79SJean-Baptiste Boric struct vrs_desc *iso9660_vrs_desc;
3779f988b79SJean-Baptiste Boric uint32_t pos;
3789f988b79SJean-Baptiste Boric int error, cnt, dpos;
3799f988b79SJean-Baptiste Boric
3809f988b79SJean-Baptiste Boric /* create ISO/Ecma-167 identification descriptors */
3819f988b79SJean-Baptiste Boric if ((iso9660_vrs_desc = calloc(1, context.sector_size)) == NULL)
3829f988b79SJean-Baptiste Boric return ENOMEM;
3839f988b79SJean-Baptiste Boric
3849f988b79SJean-Baptiste Boric /*
3859f988b79SJean-Baptiste Boric * All UDF formats should have their ISO/Ecma-167 descriptors written
3869f988b79SJean-Baptiste Boric * except when not possible due to track reservation in the case of
3879f988b79SJean-Baptiste Boric * VAT
3889f988b79SJean-Baptiste Boric */
3899f988b79SJean-Baptiste Boric if ((format_flags & FORMAT_TRACK512) == 0) {
3909f988b79SJean-Baptiste Boric dpos = (2048 + context.sector_size - 1) / context.sector_size;
3919f988b79SJean-Baptiste Boric
3929f988b79SJean-Baptiste Boric /* wipe at least 6 times 2048 byte `sectors' */
3939f988b79SJean-Baptiste Boric for (cnt = 0; cnt < 6 *dpos; cnt++) {
3949f988b79SJean-Baptiste Boric pos = layout.iso9660_vrs + cnt;
3959f988b79SJean-Baptiste Boric if ((error = udf_write_sector(iso9660_vrs_desc, pos))) {
3969f988b79SJean-Baptiste Boric free(iso9660_vrs_desc);
3979f988b79SJean-Baptiste Boric return error;
3989f988b79SJean-Baptiste Boric }
3999f988b79SJean-Baptiste Boric }
4009f988b79SJean-Baptiste Boric
4019f988b79SJean-Baptiste Boric /* common VRS fields in all written out ISO descriptors */
4029f988b79SJean-Baptiste Boric iso9660_vrs_desc->struct_type = 0;
4039f988b79SJean-Baptiste Boric iso9660_vrs_desc->version = 1;
4049f988b79SJean-Baptiste Boric pos = layout.iso9660_vrs;
4059f988b79SJean-Baptiste Boric
4069f988b79SJean-Baptiste Boric /* BEA01, NSR[23], TEA01 */
4079f988b79SJean-Baptiste Boric memcpy(iso9660_vrs_desc->identifier, "BEA01", 5);
4089f988b79SJean-Baptiste Boric if ((error = udf_write_sector(iso9660_vrs_desc, pos))) {
4099f988b79SJean-Baptiste Boric free(iso9660_vrs_desc);
4109f988b79SJean-Baptiste Boric return error;
4119f988b79SJean-Baptiste Boric }
4129f988b79SJean-Baptiste Boric pos += dpos;
4139f988b79SJean-Baptiste Boric
4149f988b79SJean-Baptiste Boric if (context.dscrver == 2)
4159f988b79SJean-Baptiste Boric memcpy(iso9660_vrs_desc->identifier, "NSR02", 5);
4169f988b79SJean-Baptiste Boric else
4179f988b79SJean-Baptiste Boric memcpy(iso9660_vrs_desc->identifier, "NSR03", 5);
4189f988b79SJean-Baptiste Boric ;
4199f988b79SJean-Baptiste Boric if ((error = udf_write_sector(iso9660_vrs_desc, pos))) {
4209f988b79SJean-Baptiste Boric free(iso9660_vrs_desc);
4219f988b79SJean-Baptiste Boric return error;
4229f988b79SJean-Baptiste Boric }
4239f988b79SJean-Baptiste Boric pos += dpos;
4249f988b79SJean-Baptiste Boric
4259f988b79SJean-Baptiste Boric memcpy(iso9660_vrs_desc->identifier, "TEA01", 5);
4269f988b79SJean-Baptiste Boric if ((error = udf_write_sector(iso9660_vrs_desc, pos))) {
4279f988b79SJean-Baptiste Boric free(iso9660_vrs_desc);
4289f988b79SJean-Baptiste Boric return error;
4299f988b79SJean-Baptiste Boric }
4309f988b79SJean-Baptiste Boric }
4319f988b79SJean-Baptiste Boric
4329f988b79SJean-Baptiste Boric free(iso9660_vrs_desc);
4339f988b79SJean-Baptiste Boric /* return success */
4349f988b79SJean-Baptiste Boric return 0;
4359f988b79SJean-Baptiste Boric }
4369f988b79SJean-Baptiste Boric
4379f988b79SJean-Baptiste Boric
4389f988b79SJean-Baptiste Boric /* --------------------------------------------------------------------- */
4399f988b79SJean-Baptiste Boric
4409f988b79SJean-Baptiste Boric /*
4419f988b79SJean-Baptiste Boric * Main function that creates and writes out disc contents based on the
4429f988b79SJean-Baptiste Boric * format_flags's that uniquely define the type of disc to create.
4439f988b79SJean-Baptiste Boric */
4449f988b79SJean-Baptiste Boric
4459f988b79SJean-Baptiste Boric int
udf_do_newfs_prefix(void)4469f988b79SJean-Baptiste Boric udf_do_newfs_prefix(void)
4479f988b79SJean-Baptiste Boric {
4489f988b79SJean-Baptiste Boric union dscrptr *zero_dscr;
4499f988b79SJean-Baptiste Boric union dscrptr *dscr;
4509f988b79SJean-Baptiste Boric struct mmc_trackinfo ti;
4519f988b79SJean-Baptiste Boric uint32_t sparable_blocks;
4529f988b79SJean-Baptiste Boric uint32_t sector_size, blockingnr;
4539f988b79SJean-Baptiste Boric uint32_t cnt, loc, len;
4549f988b79SJean-Baptiste Boric int sectcopy;
4559f988b79SJean-Baptiste Boric int error, integrity_type;
4569f988b79SJean-Baptiste Boric int data_part, metadata_part;
4579f988b79SJean-Baptiste Boric
4589f988b79SJean-Baptiste Boric /* init */
4599f988b79SJean-Baptiste Boric sector_size = mmc_discinfo.sector_size;
4609f988b79SJean-Baptiste Boric
4619f988b79SJean-Baptiste Boric /* determine span/size */
4629f988b79SJean-Baptiste Boric ti.tracknr = mmc_discinfo.first_track_last_session;
4639f988b79SJean-Baptiste Boric error = udf_update_trackinfo(&mmc_discinfo, &ti);
4649f988b79SJean-Baptiste Boric if (error)
4659f988b79SJean-Baptiste Boric return error;
4669f988b79SJean-Baptiste Boric
4679f988b79SJean-Baptiste Boric if (mmc_discinfo.sector_size < context.sector_size) {
4689f988b79SJean-Baptiste Boric fprintf(stderr, "Impossible to format: sectorsize too small\n");
4699f988b79SJean-Baptiste Boric return EIO;
4709f988b79SJean-Baptiste Boric }
4719f988b79SJean-Baptiste Boric context.sector_size = sector_size;
4729f988b79SJean-Baptiste Boric
4739f988b79SJean-Baptiste Boric /* determine blockingnr */
4749f988b79SJean-Baptiste Boric blockingnr = ti.packet_size;
4759f988b79SJean-Baptiste Boric if (blockingnr <= 1) {
4769f988b79SJean-Baptiste Boric /* paranoia on blockingnr */
4779f988b79SJean-Baptiste Boric switch (mmc_discinfo.mmc_profile) {
4789f988b79SJean-Baptiste Boric case 0x08 : /* CDROM */
4799f988b79SJean-Baptiste Boric case 0x09 : /* CD-R */
4809f988b79SJean-Baptiste Boric case 0x0a : /* CD-RW */
4819f988b79SJean-Baptiste Boric blockingnr = 32; /* UDF requirement */
4829f988b79SJean-Baptiste Boric break;
4839f988b79SJean-Baptiste Boric case 0x10 : /* DVDROM */
4849f988b79SJean-Baptiste Boric case 0x11 : /* DVD-R (DL) */
4859f988b79SJean-Baptiste Boric case 0x12 : /* DVD-RAM */
4869f988b79SJean-Baptiste Boric case 0x1b : /* DVD+R */
4879f988b79SJean-Baptiste Boric case 0x2b : /* DVD+R Dual layer */
4889f988b79SJean-Baptiste Boric case 0x13 : /* DVD-RW restricted overwrite */
4899f988b79SJean-Baptiste Boric case 0x14 : /* DVD-RW sequential */
4909f988b79SJean-Baptiste Boric blockingnr = 16; /* SCSI definition */
4919f988b79SJean-Baptiste Boric break;
4929f988b79SJean-Baptiste Boric case 0x40 : /* BDROM */
4939f988b79SJean-Baptiste Boric case 0x41 : /* BD-R Sequential recording (SRM) */
4949f988b79SJean-Baptiste Boric case 0x42 : /* BD-R Random recording (RRM) */
4959f988b79SJean-Baptiste Boric case 0x43 : /* BD-RE */
4969f988b79SJean-Baptiste Boric case 0x51 : /* HD DVD-R */
4979f988b79SJean-Baptiste Boric case 0x52 : /* HD DVD-RW */
4989f988b79SJean-Baptiste Boric blockingnr = 32; /* SCSI definition */
4999f988b79SJean-Baptiste Boric break;
5009f988b79SJean-Baptiste Boric default:
5019f988b79SJean-Baptiste Boric break;
5029f988b79SJean-Baptiste Boric }
5039f988b79SJean-Baptiste Boric }
5049f988b79SJean-Baptiste Boric if (blockingnr <= 0) {
5059f988b79SJean-Baptiste Boric printf("Can't fixup blockingnumber for device "
5069f988b79SJean-Baptiste Boric "type %d\n", mmc_discinfo.mmc_profile);
5079f988b79SJean-Baptiste Boric
5089f988b79SJean-Baptiste Boric printf("Device is not returning valid blocking"
5099f988b79SJean-Baptiste Boric " number and media type is unknown.\n");
5109f988b79SJean-Baptiste Boric
5119f988b79SJean-Baptiste Boric return EINVAL;
5129f988b79SJean-Baptiste Boric }
5139f988b79SJean-Baptiste Boric wrtrack_skew = ti.track_start % blockingnr;
5149f988b79SJean-Baptiste Boric
5159f988b79SJean-Baptiste Boric if (mmc_discinfo.mmc_class == MMC_CLASS_CD) {
5169f988b79SJean-Baptiste Boric /* not too much for CD-RW, still 20MiB */
5179f988b79SJean-Baptiste Boric sparable_blocks = 32;
5189f988b79SJean-Baptiste Boric } else {
5199f988b79SJean-Baptiste Boric /* take a value for DVD*RW mainly, BD is `defect free' */
5209f988b79SJean-Baptiste Boric sparable_blocks = 512;
5219f988b79SJean-Baptiste Boric }
5229f988b79SJean-Baptiste Boric
5239f988b79SJean-Baptiste Boric /* get layout */
5249f988b79SJean-Baptiste Boric error = udf_calculate_disc_layout(format_flags, context.min_udf,
5259f988b79SJean-Baptiste Boric wrtrack_skew,
5269f988b79SJean-Baptiste Boric ti.track_start, mmc_discinfo.last_possible_lba,
5279f988b79SJean-Baptiste Boric context.sector_size, blockingnr, sparable_blocks,
5289f988b79SJean-Baptiste Boric meta_fract);
5299f988b79SJean-Baptiste Boric
5309f988b79SJean-Baptiste Boric /* cache partition for we need it often */
5319f988b79SJean-Baptiste Boric data_part = context.data_part;
5329f988b79SJean-Baptiste Boric metadata_part = context.metadata_part;
5339f988b79SJean-Baptiste Boric
5349f988b79SJean-Baptiste Boric /* Create sparing table descriptor if applicable */
5359f988b79SJean-Baptiste Boric if (format_flags & FORMAT_SPARABLE) {
5369f988b79SJean-Baptiste Boric if ((error = udf_create_sparing_tabled()))
5379f988b79SJean-Baptiste Boric return error;
5389f988b79SJean-Baptiste Boric
5399f988b79SJean-Baptiste Boric if (check_surface) {
5409f988b79SJean-Baptiste Boric if ((error = udf_surface_check()))
5419f988b79SJean-Baptiste Boric return error;
5429f988b79SJean-Baptiste Boric }
5439f988b79SJean-Baptiste Boric }
5449f988b79SJean-Baptiste Boric
5459f988b79SJean-Baptiste Boric /* Create a generic terminator descriptor (later reused) */
5469f988b79SJean-Baptiste Boric terminator_dscr = calloc(1, sector_size);
5479f988b79SJean-Baptiste Boric if (terminator_dscr == NULL)
5489f988b79SJean-Baptiste Boric return ENOMEM;
5499f988b79SJean-Baptiste Boric udf_create_terminator(terminator_dscr, 0);
5509f988b79SJean-Baptiste Boric
5519f988b79SJean-Baptiste Boric /*
5529f988b79SJean-Baptiste Boric * Start with wipeout of VRS1 upto start of partition. This allows
5539f988b79SJean-Baptiste Boric * formatting for sequentials with the track reservation and it
5549f988b79SJean-Baptiste Boric * cleans old rubbish on rewritables. For sequentuals without the
5559f988b79SJean-Baptiste Boric * track reservation all is wiped from track start.
5569f988b79SJean-Baptiste Boric */
5579f988b79SJean-Baptiste Boric if ((zero_dscr = calloc(1, context.sector_size)) == NULL)
5589f988b79SJean-Baptiste Boric return ENOMEM;
5599f988b79SJean-Baptiste Boric
5609f988b79SJean-Baptiste Boric loc = (format_flags & FORMAT_TRACK512) ? layout.vds1 : ti.track_start;
5619f988b79SJean-Baptiste Boric for (; loc < layout.part_start_lba; loc++) {
5629f988b79SJean-Baptiste Boric if ((error = udf_write_sector(zero_dscr, loc))) {
5639f988b79SJean-Baptiste Boric free(zero_dscr);
5649f988b79SJean-Baptiste Boric return error;
5659f988b79SJean-Baptiste Boric }
5669f988b79SJean-Baptiste Boric }
5679f988b79SJean-Baptiste Boric free(zero_dscr);
5689f988b79SJean-Baptiste Boric
5699f988b79SJean-Baptiste Boric /* Create anchors */
5709f988b79SJean-Baptiste Boric for (cnt = 0; cnt < 3; cnt++) {
5719f988b79SJean-Baptiste Boric if ((error = udf_create_anchor(cnt))) {
5729f988b79SJean-Baptiste Boric return error;
5739f988b79SJean-Baptiste Boric }
5749f988b79SJean-Baptiste Boric }
5759f988b79SJean-Baptiste Boric
5769f988b79SJean-Baptiste Boric /*
5779f988b79SJean-Baptiste Boric * Create the two Volume Descriptor Sets (VDS) each containing the
5789f988b79SJean-Baptiste Boric * following descriptors : primary volume, partition space,
5799f988b79SJean-Baptiste Boric * unallocated space, logical volume, implementation use and the
5809f988b79SJean-Baptiste Boric * terminator
5819f988b79SJean-Baptiste Boric */
5829f988b79SJean-Baptiste Boric
5839f988b79SJean-Baptiste Boric /* start of volume recognision sequence building */
5849f988b79SJean-Baptiste Boric context.vds_seq = 0;
5859f988b79SJean-Baptiste Boric
5869f988b79SJean-Baptiste Boric /* Create primary volume descriptor */
5879f988b79SJean-Baptiste Boric if ((error = udf_create_primaryd()))
5889f988b79SJean-Baptiste Boric return error;
5899f988b79SJean-Baptiste Boric
5909f988b79SJean-Baptiste Boric /* Create partition descriptor */
5919f988b79SJean-Baptiste Boric if ((error = udf_create_partitiond(context.data_part, media_accesstype)))
5929f988b79SJean-Baptiste Boric return error;
5939f988b79SJean-Baptiste Boric
5949f988b79SJean-Baptiste Boric /* Create unallocated space descriptor */
5959f988b79SJean-Baptiste Boric if ((error = udf_create_unalloc_spaced()))
5969f988b79SJean-Baptiste Boric return error;
5979f988b79SJean-Baptiste Boric
5989f988b79SJean-Baptiste Boric /* Create logical volume descriptor */
5999f988b79SJean-Baptiste Boric if ((error = udf_create_logical_dscr(format_flags)))
6009f988b79SJean-Baptiste Boric return error;
6019f988b79SJean-Baptiste Boric
6029f988b79SJean-Baptiste Boric /* Create implementation use descriptor */
6039f988b79SJean-Baptiste Boric /* TODO input of fields 1,2,3 and passing them */
6049f988b79SJean-Baptiste Boric if ((error = udf_create_impvold(NULL, NULL, NULL)))
6059f988b79SJean-Baptiste Boric return error;
6069f988b79SJean-Baptiste Boric
6079f988b79SJean-Baptiste Boric /* write out what we've created so far */
6089f988b79SJean-Baptiste Boric
6099f988b79SJean-Baptiste Boric /* writeout iso9660 vrs */
6109f988b79SJean-Baptiste Boric if ((error = udf_write_iso9660_vrs()))
6119f988b79SJean-Baptiste Boric return error;
6129f988b79SJean-Baptiste Boric
6139f988b79SJean-Baptiste Boric /* Writeout anchors */
6149f988b79SJean-Baptiste Boric for (cnt = 0; cnt < 3; cnt++) {
6159f988b79SJean-Baptiste Boric dscr = (union dscrptr *) context.anchors[cnt];
6169f988b79SJean-Baptiste Boric loc = layout.anchors[cnt];
6179f988b79SJean-Baptiste Boric if ((error = udf_write_dscr_phys(dscr, loc, 1)))
6189f988b79SJean-Baptiste Boric return error;
6199f988b79SJean-Baptiste Boric
6209f988b79SJean-Baptiste Boric /* sequential media has only one anchor */
6219f988b79SJean-Baptiste Boric if (format_flags & FORMAT_SEQUENTIAL)
6229f988b79SJean-Baptiste Boric break;
6239f988b79SJean-Baptiste Boric }
6249f988b79SJean-Baptiste Boric
6259f988b79SJean-Baptiste Boric /* write out main and secondary VRS */
6269f988b79SJean-Baptiste Boric for (sectcopy = 1; sectcopy <= 2; sectcopy++) {
6279f988b79SJean-Baptiste Boric loc = (sectcopy == 1) ? layout.vds1 : layout.vds2;
6289f988b79SJean-Baptiste Boric
6299f988b79SJean-Baptiste Boric /* primary volume descriptor */
6309f988b79SJean-Baptiste Boric dscr = (union dscrptr *) context.primary_vol;
6319f988b79SJean-Baptiste Boric error = udf_write_dscr_phys(dscr, loc, 1);
6329f988b79SJean-Baptiste Boric if (error)
6339f988b79SJean-Baptiste Boric return error;
6349f988b79SJean-Baptiste Boric loc++;
6359f988b79SJean-Baptiste Boric
6369f988b79SJean-Baptiste Boric /* partition descriptor(s) */
6379f988b79SJean-Baptiste Boric for (cnt = 0; cnt < UDF_PARTITIONS; cnt++) {
6389f988b79SJean-Baptiste Boric dscr = (union dscrptr *) context.partitions[cnt];
6399f988b79SJean-Baptiste Boric if (dscr) {
6409f988b79SJean-Baptiste Boric error = udf_write_dscr_phys(dscr, loc, 1);
6419f988b79SJean-Baptiste Boric if (error)
6429f988b79SJean-Baptiste Boric return error;
6439f988b79SJean-Baptiste Boric loc++;
6449f988b79SJean-Baptiste Boric }
6459f988b79SJean-Baptiste Boric }
6469f988b79SJean-Baptiste Boric
6479f988b79SJean-Baptiste Boric /* unallocated space descriptor */
6489f988b79SJean-Baptiste Boric dscr = (union dscrptr *) context.unallocated;
6499f988b79SJean-Baptiste Boric error = udf_write_dscr_phys(dscr, loc, 1);
6509f988b79SJean-Baptiste Boric if (error)
6519f988b79SJean-Baptiste Boric return error;
6529f988b79SJean-Baptiste Boric loc++;
6539f988b79SJean-Baptiste Boric
6549f988b79SJean-Baptiste Boric /* logical volume descriptor */
6559f988b79SJean-Baptiste Boric dscr = (union dscrptr *) context.logical_vol;
6569f988b79SJean-Baptiste Boric error = udf_write_dscr_phys(dscr, loc, 1);
6579f988b79SJean-Baptiste Boric if (error)
6589f988b79SJean-Baptiste Boric return error;
6599f988b79SJean-Baptiste Boric loc++;
6609f988b79SJean-Baptiste Boric
6619f988b79SJean-Baptiste Boric /* implementation use descriptor */
6629f988b79SJean-Baptiste Boric dscr = (union dscrptr *) context.implementation;
6639f988b79SJean-Baptiste Boric error = udf_write_dscr_phys(dscr, loc, 1);
6649f988b79SJean-Baptiste Boric if (error)
6659f988b79SJean-Baptiste Boric return error;
6669f988b79SJean-Baptiste Boric loc++;
6679f988b79SJean-Baptiste Boric
6689f988b79SJean-Baptiste Boric /* terminator descriptor */
6699f988b79SJean-Baptiste Boric error = udf_write_dscr_phys(terminator_dscr, loc, 1);
6709f988b79SJean-Baptiste Boric if (error)
6719f988b79SJean-Baptiste Boric return error;
6729f988b79SJean-Baptiste Boric loc++;
6739f988b79SJean-Baptiste Boric }
6749f988b79SJean-Baptiste Boric
6759f988b79SJean-Baptiste Boric /* writeout the two sparable table descriptors (if needed) */
6769f988b79SJean-Baptiste Boric if (format_flags & FORMAT_SPARABLE) {
6779f988b79SJean-Baptiste Boric for (sectcopy = 1; sectcopy <= 2; sectcopy++) {
6789f988b79SJean-Baptiste Boric loc = (sectcopy == 1) ? layout.spt_1 : layout.spt_2;
6799f988b79SJean-Baptiste Boric dscr = (union dscrptr *) context.sparing_table;
6809f988b79SJean-Baptiste Boric len = layout.sparing_table_dscr_lbas;
6819f988b79SJean-Baptiste Boric
6829f988b79SJean-Baptiste Boric /* writeout */
6839f988b79SJean-Baptiste Boric error = udf_write_dscr_phys(dscr, loc, len);
6849f988b79SJean-Baptiste Boric if (error)
6859f988b79SJean-Baptiste Boric return error;
6869f988b79SJean-Baptiste Boric }
6879f988b79SJean-Baptiste Boric }
6889f988b79SJean-Baptiste Boric
6899f988b79SJean-Baptiste Boric /*
6909f988b79SJean-Baptiste Boric * Create unallocated space bitmap descriptor. Sequential recorded
6919f988b79SJean-Baptiste Boric * media report their own free/used space; no free/used space tables
6929f988b79SJean-Baptiste Boric * should be recorded for these.
6939f988b79SJean-Baptiste Boric */
6949f988b79SJean-Baptiste Boric if ((format_flags & (FORMAT_SEQUENTIAL | FORMAT_READONLY)) == 0) {
6959f988b79SJean-Baptiste Boric error = udf_create_space_bitmap(
6969f988b79SJean-Baptiste Boric layout.alloc_bitmap_dscr_size,
6979f988b79SJean-Baptiste Boric layout.part_size_lba,
6989f988b79SJean-Baptiste Boric &context.part_unalloc_bits[data_part]);
6999f988b79SJean-Baptiste Boric if (error)
7009f988b79SJean-Baptiste Boric return error;
7019f988b79SJean-Baptiste Boric /* TODO: freed space bitmap if applicable */
7029f988b79SJean-Baptiste Boric
7039f988b79SJean-Baptiste Boric /* mark space allocated for the unallocated space bitmap */
7049f988b79SJean-Baptiste Boric udf_mark_allocated(layout.unalloc_space, data_part,
7059f988b79SJean-Baptiste Boric layout.alloc_bitmap_dscr_size);
7069f988b79SJean-Baptiste Boric }
7079f988b79SJean-Baptiste Boric
7089f988b79SJean-Baptiste Boric /*
7099f988b79SJean-Baptiste Boric * Create metadata partition file entries and allocate and init their
7109f988b79SJean-Baptiste Boric * space and free space maps.
7119f988b79SJean-Baptiste Boric */
7129f988b79SJean-Baptiste Boric if (format_flags & FORMAT_META) {
7139f988b79SJean-Baptiste Boric error = udf_create_space_bitmap(
7149f988b79SJean-Baptiste Boric layout.meta_bitmap_dscr_size,
7159f988b79SJean-Baptiste Boric layout.meta_part_size_lba,
7169f988b79SJean-Baptiste Boric &context.part_unalloc_bits[metadata_part]);
7179f988b79SJean-Baptiste Boric if (error)
7189f988b79SJean-Baptiste Boric return error;
7199f988b79SJean-Baptiste Boric
7209f988b79SJean-Baptiste Boric error = udf_create_meta_files();
7219f988b79SJean-Baptiste Boric if (error)
7229f988b79SJean-Baptiste Boric return error;
7239f988b79SJean-Baptiste Boric
7249f988b79SJean-Baptiste Boric /* mark space allocated for meta partition and its bitmap */
7259f988b79SJean-Baptiste Boric udf_mark_allocated(layout.meta_file, data_part, 1);
7269f988b79SJean-Baptiste Boric udf_mark_allocated(layout.meta_mirror, data_part, 1);
7279f988b79SJean-Baptiste Boric udf_mark_allocated(layout.meta_bitmap, data_part, 1);
7289f988b79SJean-Baptiste Boric udf_mark_allocated(layout.meta_part_start_lba, data_part,
7299f988b79SJean-Baptiste Boric layout.meta_part_size_lba);
7309f988b79SJean-Baptiste Boric
7319f988b79SJean-Baptiste Boric /* mark space allocated for the unallocated space bitmap */
7329f988b79SJean-Baptiste Boric udf_mark_allocated(layout.meta_bitmap_space, data_part,
7339f988b79SJean-Baptiste Boric layout.meta_bitmap_dscr_size);
7349f988b79SJean-Baptiste Boric }
7359f988b79SJean-Baptiste Boric
7369f988b79SJean-Baptiste Boric /* create logical volume integrity descriptor */
7379f988b79SJean-Baptiste Boric context.num_files = 0;
7389f988b79SJean-Baptiste Boric context.num_directories = 0;
7399f988b79SJean-Baptiste Boric integrity_type = UDF_INTEGRITY_OPEN;
7409f988b79SJean-Baptiste Boric if ((error = udf_create_lvintd(integrity_type)))
7419f988b79SJean-Baptiste Boric return error;
7429f988b79SJean-Baptiste Boric
7439f988b79SJean-Baptiste Boric /* writeout initial open integrity sequence + terminator */
7449f988b79SJean-Baptiste Boric loc = layout.lvis;
7459f988b79SJean-Baptiste Boric dscr = (union dscrptr *) context.logvol_integrity;
7469f988b79SJean-Baptiste Boric error = udf_write_dscr_phys(dscr, loc, 1);
7479f988b79SJean-Baptiste Boric if (error)
7489f988b79SJean-Baptiste Boric return error;
7499f988b79SJean-Baptiste Boric loc++;
7509f988b79SJean-Baptiste Boric error = udf_write_dscr_phys(terminator_dscr, loc, 1);
7519f988b79SJean-Baptiste Boric if (error)
7529f988b79SJean-Baptiste Boric return error;
7539f988b79SJean-Baptiste Boric
7549f988b79SJean-Baptiste Boric /* create VAT if needed */
7559f988b79SJean-Baptiste Boric if (format_flags & FORMAT_VAT) {
7569f988b79SJean-Baptiste Boric context.vat_allocated = context.sector_size;
7579f988b79SJean-Baptiste Boric context.vat_contents = malloc(context.vat_allocated);
7589f988b79SJean-Baptiste Boric assert(context.vat_contents);
7599f988b79SJean-Baptiste Boric
7609f988b79SJean-Baptiste Boric udf_prepend_VAT_file();
7619f988b79SJean-Baptiste Boric }
7629f988b79SJean-Baptiste Boric
7639f988b79SJean-Baptiste Boric /* create FSD and writeout */
7649f988b79SJean-Baptiste Boric if ((error = udf_create_fsd()))
7659f988b79SJean-Baptiste Boric return error;
7669f988b79SJean-Baptiste Boric udf_mark_allocated(layout.fsd, metadata_part, 1);
7679f988b79SJean-Baptiste Boric
7689f988b79SJean-Baptiste Boric dscr = (union dscrptr *) context.fileset_desc;
7699f988b79SJean-Baptiste Boric error = udf_write_dscr_virt(dscr, layout.fsd, metadata_part, 1);
7709f988b79SJean-Baptiste Boric
7719f988b79SJean-Baptiste Boric return error;
7729f988b79SJean-Baptiste Boric }
7739f988b79SJean-Baptiste Boric
7749f988b79SJean-Baptiste Boric
7759f988b79SJean-Baptiste Boric /* specific routine for newfs to create empty rootdirectory */
7769f988b79SJean-Baptiste Boric int
udf_do_rootdir(void)7779f988b79SJean-Baptiste Boric udf_do_rootdir(void) {
7789f988b79SJean-Baptiste Boric union dscrptr *root_dscr;
7799f988b79SJean-Baptiste Boric int error;
7809f988b79SJean-Baptiste Boric
7819f988b79SJean-Baptiste Boric /* create root directory and write out */
7829f988b79SJean-Baptiste Boric assert(context.unique_id == 0x10);
7839f988b79SJean-Baptiste Boric context.unique_id = 0;
7849f988b79SJean-Baptiste Boric if ((error = udf_create_new_rootdir(&root_dscr)))
7859f988b79SJean-Baptiste Boric return error;
7869f988b79SJean-Baptiste Boric udf_mark_allocated(layout.rootdir, context.metadata_part, 1);
7879f988b79SJean-Baptiste Boric
7889f988b79SJean-Baptiste Boric error = udf_write_dscr_virt(root_dscr,
7899f988b79SJean-Baptiste Boric layout.rootdir, context.metadata_part, 1);
7909f988b79SJean-Baptiste Boric
7919f988b79SJean-Baptiste Boric free(root_dscr);
7929f988b79SJean-Baptiste Boric
7939f988b79SJean-Baptiste Boric return error;
7949f988b79SJean-Baptiste Boric }
7959f988b79SJean-Baptiste Boric
7969f988b79SJean-Baptiste Boric
7979f988b79SJean-Baptiste Boric int
udf_do_newfs_postfix(void)7989f988b79SJean-Baptiste Boric udf_do_newfs_postfix(void)
7999f988b79SJean-Baptiste Boric {
8009f988b79SJean-Baptiste Boric union dscrptr *vat_dscr;
8019f988b79SJean-Baptiste Boric union dscrptr *dscr;
8029f988b79SJean-Baptiste Boric struct long_ad vatdata_pos;
8039f988b79SJean-Baptiste Boric uint32_t loc, len, phys, sects;
8049f988b79SJean-Baptiste Boric int data_part, metadata_part;
8059f988b79SJean-Baptiste Boric int error;
8069f988b79SJean-Baptiste Boric
8079f988b79SJean-Baptiste Boric /* cache partition for we need it often */
8089f988b79SJean-Baptiste Boric data_part = context.data_part;
8099f988b79SJean-Baptiste Boric metadata_part = context.metadata_part;
8109f988b79SJean-Baptiste Boric
8119f988b79SJean-Baptiste Boric if ((format_flags & FORMAT_SEQUENTIAL) == 0) {
8129f988b79SJean-Baptiste Boric /* update lvint and mark it closed */
8139f988b79SJean-Baptiste Boric udf_update_lvintd(UDF_INTEGRITY_CLOSED);
8149f988b79SJean-Baptiste Boric
8159f988b79SJean-Baptiste Boric /* overwrite initial terminator */
8169f988b79SJean-Baptiste Boric loc = layout.lvis+1;
8179f988b79SJean-Baptiste Boric dscr = (union dscrptr *) context.logvol_integrity;
8189f988b79SJean-Baptiste Boric error = udf_write_dscr_phys(dscr, loc, 1);
8199f988b79SJean-Baptiste Boric if (error)
8209f988b79SJean-Baptiste Boric return error;
8219f988b79SJean-Baptiste Boric loc++;
8229f988b79SJean-Baptiste Boric
8239f988b79SJean-Baptiste Boric /* mark end of integrity desciptor sequence again */
8249f988b79SJean-Baptiste Boric error = udf_write_dscr_phys(terminator_dscr, loc, 1);
8259f988b79SJean-Baptiste Boric if (error)
8269f988b79SJean-Baptiste Boric return error;
8279f988b79SJean-Baptiste Boric }
8289f988b79SJean-Baptiste Boric
8299f988b79SJean-Baptiste Boric /* write out unallocated space bitmap on non sequential media */
8309f988b79SJean-Baptiste Boric if ((format_flags & (FORMAT_SEQUENTIAL | FORMAT_READONLY)) == 0) {
8319f988b79SJean-Baptiste Boric /* writeout unallocated space bitmap */
8329f988b79SJean-Baptiste Boric loc = layout.unalloc_space;
8339f988b79SJean-Baptiste Boric dscr = (union dscrptr *) (context.part_unalloc_bits[data_part]);
8349f988b79SJean-Baptiste Boric len = layout.alloc_bitmap_dscr_size;
8359f988b79SJean-Baptiste Boric error = udf_write_dscr_virt(dscr, loc, data_part, len);
8369f988b79SJean-Baptiste Boric if (error)
8379f988b79SJean-Baptiste Boric return error;
8389f988b79SJean-Baptiste Boric }
8399f988b79SJean-Baptiste Boric
8409f988b79SJean-Baptiste Boric if (format_flags & FORMAT_META) {
8419f988b79SJean-Baptiste Boric loc = layout.meta_file;
8429f988b79SJean-Baptiste Boric dscr = (union dscrptr *) context.meta_file;
8439f988b79SJean-Baptiste Boric error = udf_write_dscr_virt(dscr, loc, data_part, 1);
8449f988b79SJean-Baptiste Boric if (error)
8459f988b79SJean-Baptiste Boric return error;
8469f988b79SJean-Baptiste Boric
8479f988b79SJean-Baptiste Boric loc = layout.meta_mirror;
8489f988b79SJean-Baptiste Boric dscr = (union dscrptr *) context.meta_mirror;
8499f988b79SJean-Baptiste Boric error = udf_write_dscr_virt(dscr, loc, data_part, 1);
8509f988b79SJean-Baptiste Boric if (error)
8519f988b79SJean-Baptiste Boric return error;
8529f988b79SJean-Baptiste Boric
8539f988b79SJean-Baptiste Boric loc = layout.meta_bitmap;
8549f988b79SJean-Baptiste Boric dscr = (union dscrptr *) context.meta_bitmap;
8559f988b79SJean-Baptiste Boric error = udf_write_dscr_virt(dscr, loc, data_part, 1);
8569f988b79SJean-Baptiste Boric if (error)
8579f988b79SJean-Baptiste Boric return error;
8589f988b79SJean-Baptiste Boric
8599f988b79SJean-Baptiste Boric /* writeout unallocated space bitmap */
8609f988b79SJean-Baptiste Boric loc = layout.meta_bitmap_space;
8619f988b79SJean-Baptiste Boric dscr = (union dscrptr *)
8629f988b79SJean-Baptiste Boric (context.part_unalloc_bits[metadata_part]);
8639f988b79SJean-Baptiste Boric len = layout.meta_bitmap_dscr_size;
8649f988b79SJean-Baptiste Boric error = udf_write_dscr_virt(dscr, loc, data_part, len);
8659f988b79SJean-Baptiste Boric if (error)
8669f988b79SJean-Baptiste Boric return error;
8679f988b79SJean-Baptiste Boric }
8689f988b79SJean-Baptiste Boric
8699f988b79SJean-Baptiste Boric /* create a VAT and account for FSD+root */
8709f988b79SJean-Baptiste Boric vat_dscr = NULL;
8719f988b79SJean-Baptiste Boric if (format_flags & FORMAT_VAT) {
8729f988b79SJean-Baptiste Boric /* update lvint to reflect the newest values (no writeout) */
8739f988b79SJean-Baptiste Boric udf_update_lvintd(UDF_INTEGRITY_CLOSED);
8749f988b79SJean-Baptiste Boric
8759f988b79SJean-Baptiste Boric error = udf_append_VAT_file();
8769f988b79SJean-Baptiste Boric if (error)
8779f988b79SJean-Baptiste Boric return error;
8789f988b79SJean-Baptiste Boric
8799f988b79SJean-Baptiste Boric /* write out VAT data */
8809f988b79SJean-Baptiste Boric sects = UDF_ROUNDUP(context.vat_size, context.sector_size) /
8819f988b79SJean-Baptiste Boric context.sector_size;
8829f988b79SJean-Baptiste Boric layout.vat = context.data_alloc_pos;
8839f988b79SJean-Baptiste Boric udf_data_alloc(sects, &vatdata_pos);
8849f988b79SJean-Baptiste Boric
8859f988b79SJean-Baptiste Boric loc = udf_rw32(vatdata_pos.loc.lb_num);
8869f988b79SJean-Baptiste Boric phys = context.vtop_offset[context.data_part] + loc;
8879f988b79SJean-Baptiste Boric
8889f988b79SJean-Baptiste Boric error = udf_write_phys(context.vat_contents, phys, sects);
8899f988b79SJean-Baptiste Boric if (error)
8909f988b79SJean-Baptiste Boric return error;
8919f988b79SJean-Baptiste Boric loc += sects;
8929f988b79SJean-Baptiste Boric
8939f988b79SJean-Baptiste Boric /* create new VAT descriptor */
8949f988b79SJean-Baptiste Boric error = udf_create_VAT(&vat_dscr);
8959f988b79SJean-Baptiste Boric if (error)
8969f988b79SJean-Baptiste Boric return error;
8979f988b79SJean-Baptiste Boric context.data_alloc_pos++;
8989f988b79SJean-Baptiste Boric loc++;
8999f988b79SJean-Baptiste Boric
9009f988b79SJean-Baptiste Boric error = udf_write_dscr_virt(vat_dscr, loc, metadata_part, 1);
9019f988b79SJean-Baptiste Boric free(vat_dscr);
9029f988b79SJean-Baptiste Boric if (error)
9039f988b79SJean-Baptiste Boric return error;
9049f988b79SJean-Baptiste Boric }
9059f988b79SJean-Baptiste Boric
9069f988b79SJean-Baptiste Boric /* done */
9079f988b79SJean-Baptiste Boric return 0;
9089f988b79SJean-Baptiste Boric }
909