/* $NetBSD: udf_core.h,v 1.3 2022/08/07 11:06:18 andvar Exp $ */ /* * Copyright (c) 2006, 2008, 2021, 2022 Reinoud Zandijk * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef _FS_UDF_CORE_H_ #define _FS_UDF_CORE_H_ #if 0 # ifndef DEBUG # define DEBUG # endif #endif #include #include #include "udf_bswap.h" #include "udf_osta.h" #if !HAVE_NBTOOL_CONFIG_H #define _EXPOSE_MMC #include #include #else #include "udf/cdio_mmc_structs.h" #include "../../sys/fs/udf/ecma167-udf.h" #endif /* format flags indicating properties of disc to create */ #define FORMAT_WRITEONCE 0x00001 #define FORMAT_SEQUENTIAL 0x00002 #define FORMAT_REWRITABLE 0x00004 #define FORMAT_SPAREABLE 0x00008 #define FORMAT_META 0x00010 #define FORMAT_LOW 0x00020 #define FORMAT_VAT 0x00040 #define FORMAT_WORM 0x00080 #define FORMAT_TRACK512 0x00100 #define FORMAT_INVALID 0x00200 #define FORMAT_READONLY 0x00400 #define FORMAT_FLAGBITS \ "\10\1WRITEONCE\2SEQUENTIAL\3REWRITABLE\4SPAREABLE\5META\6LOW" \ "\7VAT\10WORM\11TRACK512\12INVALID\13READONLY" /* writing strategy */ #define UDF_WRITE_SEQUENTIAL 1 #define UDF_WRITE_PACKET 2 /* with fill-in if needed */ #define UDF_MAX_QUEUELEN 400 /* must hold all pre-partition space */ /* structure space */ #define UDF_ANCHORS 4 /* 256, 512, N-256, N */ #define UDF_PARTITIONS 4 /* overkill */ #define UDF_PMAPS 4 /* overkill */ /* misc constants */ #define UDF_MAX_NAMELEN 255 /* as per SPEC */ #define UDF_LVDINT_SEGMENTS 10 /* big overkill */ #define UDF_LVINT_LOSSAGE 4 /* lose 2 openings */ #define UDF_MAX_ALLOC_EXTENTS 5 /* overkill */ /* translation constants */ #define UDF_VTOP_RAWPART UDF_PMAPS /* [0..UDF_PMAPS> are normal */ /* virtual to physical mapping types */ #define UDF_VTOP_TYPE_RAW 0 #define UDF_VTOP_TYPE_UNKNOWN 0 #define UDF_VTOP_TYPE_PHYS 1 #define UDF_VTOP_TYPE_VIRT 2 #define UDF_VTOP_TYPE_SPAREABLE 3 #define UDF_VTOP_TYPE_META 4 #define UDF_TRANS_ZERO ((uint64_t) -1) #define UDF_TRANS_UNMAPPED ((uint64_t) -2) #define UDF_TRANS_INTERN ((uint64_t) -3) #define UDF_MAX_SECTOR ((uint64_t) -10) /* high water mark */ /* handys */ #define UDF_ROUNDUP(val, gran) \ ((uint64_t) (gran) * (((uint64_t)(val) + (gran)-1) / (gran))) #define UDF_ROUNDDOWN(val, gran) \ ((uint64_t) (gran) * (((uint64_t)(val)) / (gran))) /* default */ #define UDF_META_PERC 20 /* picked */ /* disc offsets for various structures and their sizes */ struct udf_disclayout { uint32_t wrtrack_skew; uint32_t iso9660_vrs; uint32_t anchors[UDF_ANCHORS]; uint32_t vds1_size, vds2_size, vds1, vds2; uint32_t lvis_size, lvis; uint32_t first_lba, last_lba; uint32_t blockingnr, align_blockingnr, spareable_blockingnr; uint32_t meta_blockingnr, meta_alignment; /* spareables */ uint32_t spareable_blocks; uint32_t spareable_area, spareable_area_size; uint32_t sparing_table_dscr_lbas; uint32_t spt_1, spt_2; /* metadata partition */ uint32_t meta_file, meta_mirror, meta_bitmap; uint32_t meta_part_start_lba, meta_part_size_lba; uint32_t meta_bitmap_dscr_size; uint32_t meta_bitmap_space; /* main partition */ uint32_t part_start_lba, part_size_lba; uint32_t alloc_bitmap_dscr_size; uint32_t unalloc_space, freed_space; /* main structures */ uint32_t fsd, rootdir, vat; }; struct udf_lvintq { uint32_t start; uint32_t end; uint32_t pos; uint32_t wpos; }; /* all info about discs and descriptors building */ struct udf_create_context { /* descriptors */ int dscrver; /* 2 or 3 */ int min_udf; /* hex */ int max_udf; /* hex */ int serialnum; /* format serialno */ int gmtoff; /* in minutes */ int meta_perc; /* format parameter */ int check_surface; /* for spareables */ int create_new_session; /* for non empty recordables */ uint32_t sector_size; int media_accesstype; int format_flags; int write_strategy; /* identification */ char *logvol_name; char *primary_name; char *volset_name; char *fileset_name; char const *app_name; char const *impl_name; int app_version_main; int app_version_sub; /* building */ int vds_seq; /* for building functions */ /* constructed structures */ struct anchor_vdp *anchors[UDF_ANCHORS]; /* anchors to VDS */ struct pri_vol_desc *primary_vol; /* identification */ struct logvol_desc *logical_vol; /* main mapping v->p */ struct unalloc_sp_desc *unallocated; /* free UDF space */ struct impvol_desc *implementation; /* likely redundant */ struct logvol_int_desc *logvol_integrity; /* current integrity */ struct part_desc *partitions[UDF_PARTITIONS]; /* partitions */ struct space_bitmap_desc*part_unalloc_bits[UDF_PARTITIONS]; struct space_bitmap_desc*part_freed_bits [UDF_PARTITIONS]; /* track information */ struct mmc_trackinfo first_ti_partition; struct mmc_trackinfo first_ti; struct mmc_trackinfo last_ti; /* current partitions for allocation */ int data_part; int metadata_part; int fids_part; /* current highest file unique_id */ uint64_t unique_id; /* block numbers as offset in partition, building ONLY! */ uint32_t alloc_pos[UDF_PARTITIONS]; /* derived; points *into* other structures */ struct udf_logvol_info *logvol_info; /* inside integrity */ /* fileset and root directories */ struct fileset_desc *fileset_desc; /* normally one */ /* logical to physical translations */ int vtop[UDF_PMAPS+1]; /* vpartnr trans */ int vtop_tp[UDF_PMAPS+1]; /* type of trans */ /* spareable */ struct udf_sparing_table*sparing_table; /* replacements */ /* VAT file */ uint32_t vat_size; /* length */ uint32_t vat_allocated; /* allocated length */ uint32_t vat_start; /* offset 1st entry */ uint8_t *vat_contents; /* the VAT */ /* meta data partition */ struct extfile_entry *meta_file; struct extfile_entry *meta_mirror; struct extfile_entry *meta_bitmap; /* lvint */ uint32_t num_files; uint32_t num_directories; uint32_t part_size[UDF_PARTITIONS]; uint32_t part_free[UDF_PARTITIONS]; /* fsck */ union dscrptr *vds_buf; int vds_size; struct udf_lvintq lvint_trace[UDF_LVDINT_SEGMENTS]; /* fsck */ uint8_t *lvint_history; /* fsck */ int lvint_history_len; /* fsck */ int lvint_history_wpos; /* fsck */ int lvint_history_ondisc_len; /* fsck */ }; /* global variables describing disc and format */ extern struct udf_create_context context; extern struct udf_disclayout layout; extern struct mmc_discinfo mmc_discinfo; /* device: disc info */ extern int dev_fd_rdonly; /* device: open readonly! */ extern int dev_fd; /* device: file descriptor */ extern struct stat dev_fd_stat; /* device: last stat info */ extern char *dev_name; /* device: name */ extern int emul_mmc_profile; /* for files */ extern int emul_packetsize; /* for discs and files */ extern int emul_sectorsize; /* for files */ extern off_t emul_size; /* for files */ extern uint32_t wrtrack_skew; /* offset for write sector0 */ /* prototypes */ extern void udf_init_create_context(void); extern int a_udf_version(const char *s, const char *id_type); extern int is_zero(void *blob, int size); extern uint32_t udf_bytes_to_sectors(uint64_t bytes); extern int udf_calculate_disc_layout(int min_udf, uint32_t first_lba, uint32_t last_lba, uint32_t sector_size, uint32_t blockingnr); extern void udf_dump_layout(void); extern int udf_spareable_blocks(void); extern int udf_spareable_blockingnr(void); extern void udf_osta_charset(struct charspec *charspec); extern void udf_encode_osta_id(char *osta_id, uint16_t len, char *text); extern void udf_to_unix_name(char *result, int result_len, char *id, int len, struct charspec *chsp); extern void unix_to_udf_name(char *result, uint8_t *result_len, char const *name, int name_len, struct charspec *chsp); extern void udf_set_regid(struct regid *regid, char const *name); extern void udf_add_domain_regid(struct regid *regid); extern void udf_add_udf_regid(struct regid *regid); extern void udf_add_impl_regid(struct regid *regid); extern void udf_add_app_regid(struct regid *regid); extern int udf_check_tag(void *blob); extern int udf_check_tag_payload(void *blob, uint32_t max_length); extern int udf_check_tag_and_location(void *blob, uint32_t location); extern int udf_validate_tag_sum(union dscrptr *dscr); extern int udf_validate_tag_and_crc_sums(union dscrptr *dscr); extern void udf_set_timestamp_now(struct timestamp *timestamp); extern void udf_timestamp_to_timespec(struct timestamp *timestamp, struct timespec *timespec); extern void udf_timespec_to_timestamp(struct timespec *timespec, struct timestamp *timestamp); extern void udf_inittag(struct desc_tag *tag, int tagid, uint32_t loc); extern int udf_create_anchor(int num); extern void udf_create_terminator(union dscrptr *dscr, uint32_t loc); extern int udf_create_primaryd(void); extern int udf_create_partitiond(int part_num); extern int udf_create_unalloc_spaced(void); extern int udf_create_sparing_tabled(void); extern int udf_create_space_bitmap(uint32_t dscr_size, uint32_t part_size_lba, struct space_bitmap_desc **sbdp); extern int udf_create_logical_dscr(void); extern int udf_create_impvold(char *field1, char *field2, char *field3); extern int udf_create_fsd(void); extern int udf_create_lvintd(int type); extern void udf_update_lvintd(int type); extern uint16_t udf_find_raw_phys(uint16_t raw_phys_part); extern int udf_register_bad_block(uint32_t location); extern void udf_mark_allocated(uint32_t start_lb, int partnr, uint32_t blocks); extern int udf_impl_extattr_check(struct impl_extattr_entry *implext); extern void udf_calc_impl_extattr_checksum(struct impl_extattr_entry *implext); extern int udf_extattr_search_intern(union dscrptr *dscr, uint32_t sattr, char const *sattrname, uint32_t *offsetp, uint32_t *lengthp); extern int udf_create_new_fe(struct file_entry **fep, int file_type, struct stat *st); extern int udf_create_new_efe(struct extfile_entry **efep, int file_type, struct stat *st); extern int udf_encode_symlink(uint8_t **pathbufp, uint32_t *pathlenp, char *target); extern void udf_advance_uniqueid(void); extern uint32_t udf_tagsize(union dscrptr *dscr, uint32_t lb_size); extern int udf_fidsize(struct fileid_desc *fid); extern void udf_create_fid(uint32_t diroff, struct fileid_desc *fid, char *name, int namelen, struct long_ad *ref); extern int udf_create_parentfid(struct fileid_desc *fid, struct long_ad *parent); extern int udf_create_meta_files(void); extern int udf_create_new_rootdir(union dscrptr **dscr); extern int udf_create_VAT(union dscrptr **vat_dscr, struct long_ad *vatdata_loc); extern void udf_prepend_VAT_file(void); extern void udf_vat_update(uint32_t virt, uint32_t phys); extern int udf_append_VAT_file(void); extern int udf_writeout_VAT(void); extern int udf_opendisc(const char *device, int open_flags); extern void udf_closedisc(void); extern int udf_prepare_disc(void); extern int udf_update_discinfo(void); extern int udf_update_trackinfo(struct mmc_trackinfo *ti); extern int udf_get_blockingnr(struct mmc_trackinfo *ti); extern void udf_synchronise_caches(void); extern void udf_suspend_writing(void); extern void udf_allow_writing(void); extern int udf_write_iso9660_vrs(void); /* address translation */ extern int udf_translate_vtop(uint32_t lb_num, uint16_t vpart, uint32_t *lb_numres, uint32_t *extres); /* basic sector read/write with caching */ extern int udf_read_sector(void *sector, uint64_t location); extern int udf_write_sector(void *sector, uint64_t location); /* extent reading and writing */ extern int udf_read_phys(void *blob, uint32_t location, uint32_t sects); extern int udf_write_phys(void *blob, uint32_t location, uint32_t sects); extern int udf_read_virt(void *blob, uint32_t location, uint16_t vpart, uint32_t sectors); extern int udf_write_virt(void *blob, uint32_t location, uint16_t vpart, uint32_t sectors); extern int udf_read_dscr_phys(uint32_t sector, union dscrptr **dstp); extern int udf_write_dscr_phys(union dscrptr *dscr, uint32_t location, uint32_t sects); extern int udf_read_dscr_virt(uint32_t sector, uint16_t vpart, union dscrptr **dstp); extern int udf_write_dscr_virt(union dscrptr *dscr, uint32_t location, uint16_t vpart, uint32_t sects); extern void udf_metadata_alloc(int nblk, struct long_ad *pos); extern void udf_data_alloc(int nblk, struct long_ad *pos); extern void udf_fids_alloc(int nblk, struct long_ad *pos); extern int udf_derive_format(int req_enable, int req_disable); extern int udf_proces_names(void); extern int udf_surface_check(void); extern int udf_do_newfs_prefix(void); extern int udf_do_rootdir(void); extern int udf_do_newfs_postfix(void); extern void udf_dump_discinfo(struct mmc_discinfo *di); #endif /* _UDF_CORE_H_ */