1/* $NetBSD: udf_core.h,v 1.3 2022/08/07 11:06:18 andvar Exp $ */
2
3/*
4 * Copyright (c) 2006, 2008, 2021, 2022 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
29#ifndef _FS_UDF_CORE_H_
30#define _FS_UDF_CORE_H_
31
32
33#if 0
34# ifndef DEBUG
35#   define DEBUG
36#  endif
37#endif
38
39
40#include <sys/types.h>
41#include <sys/stat.h>
42#include "udf_bswap.h"
43#include "udf_osta.h"
44
45#if !HAVE_NBTOOL_CONFIG_H
46#define _EXPOSE_MMC
47#include <sys/cdio.h>
48#include <fs/udf/ecma167-udf.h>
49#else
50#include "udf/cdio_mmc_structs.h"
51#include "../../sys/fs/udf/ecma167-udf.h"
52#endif
53
54
55/* format flags indicating properties of disc to create */
56#define FORMAT_WRITEONCE	0x00001
57#define FORMAT_SEQUENTIAL	0x00002
58#define FORMAT_REWRITABLE	0x00004
59#define FORMAT_SPAREABLE	0x00008
60#define FORMAT_META		0x00010
61#define FORMAT_LOW		0x00020
62#define FORMAT_VAT		0x00040
63#define FORMAT_WORM		0x00080
64#define FORMAT_TRACK512		0x00100
65#define FORMAT_INVALID		0x00200
66#define FORMAT_READONLY		0x00400
67#define FORMAT_FLAGBITS \
68    "\10\1WRITEONCE\2SEQUENTIAL\3REWRITABLE\4SPAREABLE\5META\6LOW" \
69    "\7VAT\10WORM\11TRACK512\12INVALID\13READONLY"
70
71/* writing strategy */
72#define UDF_WRITE_SEQUENTIAL	1
73#define UDF_WRITE_PACKET	2	/* with fill-in if needed */
74#define UDF_MAX_QUEUELEN	400	/* must hold all pre-partition space */
75
76/* structure space */
77#define UDF_ANCHORS		4	/* 256, 512, N-256, N */
78#define UDF_PARTITIONS		4	/* overkill */
79#define UDF_PMAPS		4	/* overkill */
80
81/* misc constants */
82#define UDF_MAX_NAMELEN		255	/* as per SPEC */
83#define UDF_LVDINT_SEGMENTS	10	/* big overkill */
84#define UDF_LVINT_LOSSAGE	4	/* lose 2 openings */
85#define UDF_MAX_ALLOC_EXTENTS	5	/* overkill */
86
87/* translation constants */
88#define UDF_VTOP_RAWPART UDF_PMAPS	/* [0..UDF_PMAPS> are normal     */
89
90/* virtual to physical mapping types */
91#define UDF_VTOP_TYPE_RAW            0
92#define UDF_VTOP_TYPE_UNKNOWN        0
93#define UDF_VTOP_TYPE_PHYS           1
94#define UDF_VTOP_TYPE_VIRT           2
95#define UDF_VTOP_TYPE_SPAREABLE      3
96#define UDF_VTOP_TYPE_META           4
97
98#define UDF_TRANS_ZERO		((uint64_t) -1)
99#define UDF_TRANS_UNMAPPED	((uint64_t) -2)
100#define UDF_TRANS_INTERN	((uint64_t) -3)
101#define UDF_MAX_SECTOR		((uint64_t) -10)	/* high water mark */
102
103/* handys */
104#define UDF_ROUNDUP(val, gran) \
105	((uint64_t) (gran) * (((uint64_t)(val) + (gran)-1) / (gran)))
106
107#define UDF_ROUNDDOWN(val, gran) \
108	((uint64_t) (gran) * (((uint64_t)(val)) / (gran)))
109
110/* default */
111#define UDF_META_PERC  20	/* picked */
112
113
114/* disc offsets for various structures and their sizes */
115struct udf_disclayout {
116	uint32_t wrtrack_skew;
117
118	uint32_t iso9660_vrs;
119	uint32_t anchors[UDF_ANCHORS];
120	uint32_t vds1_size, vds2_size, vds1, vds2;
121	uint32_t lvis_size, lvis;
122
123	uint32_t first_lba, last_lba;
124	uint32_t blockingnr, align_blockingnr, spareable_blockingnr;
125	uint32_t meta_blockingnr, meta_alignment;
126
127	/* spareables */
128	uint32_t spareable_blocks;
129	uint32_t spareable_area, spareable_area_size;
130	uint32_t sparing_table_dscr_lbas;
131	uint32_t spt_1, spt_2;
132
133	/* metadata partition */
134	uint32_t meta_file, meta_mirror, meta_bitmap;
135	uint32_t meta_part_start_lba, meta_part_size_lba;
136	uint32_t meta_bitmap_dscr_size;
137	uint32_t meta_bitmap_space;
138
139	/* main partition */
140	uint32_t part_start_lba, part_size_lba;
141	uint32_t alloc_bitmap_dscr_size;
142	uint32_t unalloc_space, freed_space;
143
144	/* main structures */
145	uint32_t fsd, rootdir, vat;
146
147};
148
149
150struct udf_lvintq {
151	uint32_t		start;
152	uint32_t		end;
153	uint32_t		pos;
154	uint32_t		wpos;
155};
156
157
158/* all info about discs and descriptors building */
159struct udf_create_context {
160	/* descriptors */
161	int	 dscrver;		/* 2 or 3          */
162	int	 min_udf;		/* hex             */
163	int	 max_udf;		/* hex             */
164	int	 serialnum;		/* format serialno */
165
166	int	 gmtoff;		/* in minutes	             */
167	int	 meta_perc;		/* format parameter          */
168	int	 check_surface;		/* for spareables            */
169	int	 create_new_session;	/* for non empty recordables */
170
171	uint32_t sector_size;
172	int	 media_accesstype;
173	int	 format_flags;
174	int	 write_strategy;
175
176	/* identification */
177	char	*logvol_name;
178	char	*primary_name;
179	char	*volset_name;
180	char	*fileset_name;
181
182	char const *app_name;
183	char const *impl_name;
184	int	 app_version_main;
185	int	 app_version_sub;
186
187	/* building */
188	int	 vds_seq;	/* for building functions  */
189
190	/* constructed structures */
191	struct anchor_vdp	*anchors[UDF_ANCHORS];	/* anchors to VDS    */
192	struct pri_vol_desc	*primary_vol;		/* identification    */
193	struct logvol_desc	*logical_vol;		/* main mapping v->p */
194	struct unalloc_sp_desc	*unallocated;		/* free UDF space    */
195	struct impvol_desc	*implementation;	/* likely redundant  */
196	struct logvol_int_desc	*logvol_integrity;	/* current integrity */
197	struct part_desc	*partitions[UDF_PARTITIONS]; /* partitions   */
198
199	struct space_bitmap_desc*part_unalloc_bits[UDF_PARTITIONS];
200	struct space_bitmap_desc*part_freed_bits  [UDF_PARTITIONS];
201
202	/* track information */
203	struct mmc_trackinfo	 first_ti_partition;
204	struct mmc_trackinfo	 first_ti;
205	struct mmc_trackinfo	 last_ti;
206
207	/* current partitions for allocation */
208	int	data_part;
209	int	metadata_part;
210	int	fids_part;
211
212	/* current highest file unique_id */
213	uint64_t unique_id;
214
215	/* block numbers as offset in partition, building ONLY! */
216	uint32_t alloc_pos[UDF_PARTITIONS];
217
218	/* derived; points *into* other structures */
219	struct udf_logvol_info	*logvol_info;		/* inside integrity  */
220
221	/* fileset and root directories */
222	struct fileset_desc	*fileset_desc;		/* normally one      */
223
224	/* logical to physical translations */
225	int 			 vtop[UDF_PMAPS+1];	/* vpartnr trans     */
226	int			 vtop_tp[UDF_PMAPS+1];	/* type of trans     */
227
228	/* spareable */
229	struct udf_sparing_table*sparing_table;		/* replacements      */
230
231	/* VAT file */
232	uint32_t		 vat_size;		/* length */
233	uint32_t		 vat_allocated;		/* allocated length */
234	uint32_t		 vat_start;		/* offset 1st entry */
235	uint8_t			*vat_contents;		/* the VAT */
236
237	/* meta data partition */
238	struct extfile_entry	*meta_file;
239	struct extfile_entry	*meta_mirror;
240	struct extfile_entry	*meta_bitmap;
241
242	/* lvint */
243	uint32_t	 	 num_files;
244	uint32_t		 num_directories;
245	uint32_t		 part_size[UDF_PARTITIONS];
246	uint32_t		 part_free[UDF_PARTITIONS];
247
248	/* fsck */
249	union dscrptr		*vds_buf;
250	int			 vds_size;
251	struct udf_lvintq	 lvint_trace[UDF_LVDINT_SEGMENTS]; /* fsck   */
252	uint8_t			*lvint_history;			   /* fsck   */
253	int			 lvint_history_len;		   /* fsck   */
254	int			 lvint_history_wpos;		   /* fsck   */
255	int			 lvint_history_ondisc_len;	   /* fsck   */
256};
257
258
259/* global variables describing disc and format */
260extern struct udf_create_context context;
261extern struct udf_disclayout     layout;
262extern struct mmc_discinfo mmc_discinfo;  /* device: disc info		   */
263
264extern int		dev_fd_rdonly;	  /* device: open readonly!	   */
265extern int	 	dev_fd;		  /* device: file descriptor	   */
266extern struct stat	dev_fd_stat;	  /* device: last stat info	   */
267extern char	       *dev_name;	  /* device: name		   */
268extern int	 	emul_mmc_profile; /* for files			   */
269extern int		emul_packetsize;  /* for discs and files	   */
270extern int		emul_sectorsize;  /* for files		    	   */
271extern off_t		emul_size;	  /* for files			   */
272extern uint32_t		wrtrack_skew;	  /* offset for write sector0	   */
273
274
275/* prototypes */
276extern void udf_init_create_context(void);
277extern int a_udf_version(const char *s, const char *id_type);
278extern int is_zero(void *blob, int size);
279extern uint32_t udf_bytes_to_sectors(uint64_t bytes);
280
281extern int udf_calculate_disc_layout(int min_udf,
282	uint32_t first_lba, uint32_t last_lba,
283	uint32_t sector_size, uint32_t blockingnr);
284extern void udf_dump_layout(void);
285extern int udf_spareable_blocks(void);
286extern int udf_spareable_blockingnr(void);
287
288extern void udf_osta_charset(struct charspec *charspec);
289extern void udf_encode_osta_id(char *osta_id, uint16_t len, char *text);
290extern void udf_to_unix_name(char *result, int result_len, char *id, int len,
291	struct charspec *chsp);
292extern void unix_to_udf_name(char *result, uint8_t *result_len,
293	char const *name, int name_len, struct charspec *chsp);
294
295extern void udf_set_regid(struct regid *regid, char const *name);
296extern void udf_add_domain_regid(struct regid *regid);
297extern void udf_add_udf_regid(struct regid *regid);
298extern void udf_add_impl_regid(struct regid *regid);
299extern void udf_add_app_regid(struct regid *regid);
300
301extern int udf_check_tag(void *blob);
302extern int udf_check_tag_payload(void *blob, uint32_t max_length);
303extern int udf_check_tag_and_location(void *blob, uint32_t location);
304extern int udf_validate_tag_sum(union dscrptr *dscr);
305extern int udf_validate_tag_and_crc_sums(union dscrptr *dscr);
306
307extern void udf_set_timestamp_now(struct timestamp *timestamp);
308extern void udf_timestamp_to_timespec(struct timestamp *timestamp,
309	struct timespec *timespec);
310extern void udf_timespec_to_timestamp(struct timespec *timespec,
311	struct timestamp *timestamp);
312
313extern void udf_inittag(struct desc_tag *tag, int tagid, uint32_t loc);
314extern int udf_create_anchor(int num);
315
316extern void udf_create_terminator(union dscrptr *dscr, uint32_t loc);
317extern int udf_create_primaryd(void);
318extern int udf_create_partitiond(int part_num);
319extern int udf_create_unalloc_spaced(void);
320extern int udf_create_sparing_tabled(void);
321extern int udf_create_space_bitmap(uint32_t dscr_size, uint32_t part_size_lba,
322	struct space_bitmap_desc **sbdp);
323extern int udf_create_logical_dscr(void);
324extern int udf_create_impvold(char *field1, char *field2, char *field3);
325extern int udf_create_fsd(void);
326extern int udf_create_lvintd(int type);
327extern void udf_update_lvintd(int type);
328extern uint16_t udf_find_raw_phys(uint16_t raw_phys_part);
329
330extern int udf_register_bad_block(uint32_t location);
331extern void udf_mark_allocated(uint32_t start_lb, int partnr, uint32_t blocks);
332
333extern int udf_impl_extattr_check(struct impl_extattr_entry *implext);
334extern void udf_calc_impl_extattr_checksum(struct impl_extattr_entry *implext);
335extern int udf_extattr_search_intern(union dscrptr *dscr,
336	uint32_t sattr, char const *sattrname,
337	uint32_t *offsetp, uint32_t *lengthp);
338
339extern int udf_create_new_fe(struct file_entry **fep, int file_type,
340	struct stat *st);
341extern int udf_create_new_efe(struct extfile_entry **efep, int file_type,
342	struct stat *st);
343
344extern int udf_encode_symlink(uint8_t **pathbufp, uint32_t *pathlenp, char *target);
345
346extern void udf_advance_uniqueid(void);
347extern uint32_t udf_tagsize(union dscrptr *dscr, uint32_t lb_size);
348extern int udf_fidsize(struct fileid_desc *fid);
349extern void udf_create_fid(uint32_t diroff, struct fileid_desc *fid,
350	char *name, int namelen, struct long_ad *ref);
351extern int udf_create_parentfid(struct fileid_desc *fid, struct long_ad *parent);
352
353extern int udf_create_meta_files(void);
354extern int udf_create_new_rootdir(union dscrptr **dscr);
355
356extern int udf_create_VAT(union dscrptr **vat_dscr, struct long_ad *vatdata_loc);
357extern void udf_prepend_VAT_file(void);
358extern void udf_vat_update(uint32_t virt, uint32_t phys);
359extern int udf_append_VAT_file(void);
360extern int udf_writeout_VAT(void);
361
362extern int udf_opendisc(const char *device, int open_flags);
363extern void udf_closedisc(void);
364extern int udf_prepare_disc(void);
365extern int udf_update_discinfo(void);
366extern int udf_update_trackinfo(struct mmc_trackinfo *ti);
367extern int udf_get_blockingnr(struct mmc_trackinfo *ti);
368extern void udf_synchronise_caches(void);
369extern void udf_suspend_writing(void);
370extern void udf_allow_writing(void);
371
372extern int udf_write_iso9660_vrs(void);
373
374/* address translation */
375extern int udf_translate_vtop(uint32_t lb_num, uint16_t vpart,
376	uint32_t *lb_numres, uint32_t *extres);
377
378/* basic sector read/write with caching */
379extern int udf_read_sector(void *sector, uint64_t location);
380extern int udf_write_sector(void *sector, uint64_t location);
381
382/* extent reading and writing */
383extern int udf_read_phys(void *blob, uint32_t location, uint32_t sects);
384extern int udf_write_phys(void *blob, uint32_t location, uint32_t sects);
385
386extern int udf_read_virt(void *blob, uint32_t location, uint16_t vpart,
387	uint32_t sectors);
388extern int udf_write_virt(void *blob, uint32_t location, uint16_t vpart,
389	uint32_t sectors);
390
391extern int udf_read_dscr_phys(uint32_t sector, union dscrptr **dstp);
392extern int udf_write_dscr_phys(union dscrptr *dscr, uint32_t location,
393	uint32_t sects);
394
395extern int udf_read_dscr_virt(uint32_t sector, uint16_t vpart,
396	union dscrptr **dstp);
397extern int udf_write_dscr_virt(union dscrptr *dscr,
398	uint32_t location, uint16_t vpart, uint32_t sects);
399
400extern void udf_metadata_alloc(int nblk, struct long_ad *pos);
401extern void udf_data_alloc(int nblk, struct long_ad *pos);
402extern void udf_fids_alloc(int nblk, struct long_ad *pos);
403
404extern int udf_derive_format(int req_enable, int req_disable);
405extern int udf_proces_names(void);
406extern int udf_surface_check(void);
407
408extern int udf_do_newfs_prefix(void);
409extern int udf_do_rootdir(void);
410extern int udf_do_newfs_postfix(void);
411
412extern void udf_dump_discinfo(struct mmc_discinfo *di);
413
414#endif /* _UDF_CORE_H_ */
415