1 /* $NetBSD$ */
2 
3 /*
4  * File "udf.h" is part of the UDFclient toolkit.
5  * File $Id: udf.h,v 1.149 2015/08/05 18:26:30 reinoud Exp $ $Name:  $
6  *
7  * Copyright (c) 2003, 2004, 2005, 2006, 2011
8  * 	Reinoud Zandijk <reinoud@netbsd.org>
9  * All rights reserved.
10  *
11  * The UDFclient toolkit is distributed under the Clarified Artistic Licence.
12  * A copy of the licence is included in the distribution as
13  * `LICENCE.clearified.artistic' and a copy of the licence can also be
14  * requested at the GNU foundantion's website.
15  *
16  * Visit the UDFclient toolkit homepage http://www.13thmonkey.org/udftoolkit/
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  *
29  */
30 
31 
32 #ifndef _UDF_H_
33 #define _UDF_H_
34 
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <dirent.h>
38 #include <sys/stat.h>
39 #include <sys/types.h>
40 #include <inttypes.h>
41 #include "dirhash.h"
42 
43 #ifdef NO_INT_FMTIO
44 	/* assume 32 bits :-/ */
45 #ifndef PRIu32
46 #	define PRIu32  "u"
47 #	define PRIx32  "x"
48 #	define PRIu64 "lld"
49 #	define PRIx64 "llx"
50 #endif
51 #endif
52 
53 
54 /* exported flags */
55 extern int udf_verbose;
56 
57 #define UDF_MNT_RDONLY		   1
58 #define UDF_MNT_FORCE		   2
59 #define UDF_MNT_BSWAP		   4
60 
61 #define UDF_VERBLEV_NONE	   0
62 #define UDF_VERBLEV_ACTIONS	   1
63 #define UDF_VERBLEV_TABLES	   2
64 #define UDF_VERBLEV_MAX		   3
65 
66 /* constants to identify what kind of identifier we are dealing with */
67 #define UDF_REGID_DOMAIN	   1
68 #define UDF_REGID_UDF		   2
69 #define UDF_REGID_IMPLEMENTATION   3
70 #define UDF_REGID_APPLICATION	   4
71 #define UDF_REGID_NAME		  99	/* 99? */
72 
73 /* RW content hint for allocation and other purposes */
74 #define UDF_C_DSCR	0
75 #define UDF_C_USERDATA	1
76 #define UDF_C_FIDS	2
77 #define UDF_C_NODE	3
78 
79 
80 
81 /* Configuration */
82 
83 #define UDF_MINFREE_LOGVOL	(128*1024)	/* max sector is 64kb, give 2 (sorry) slack; use with care */
84 #define UDF_LOOKUP_READAHEAD	64		/* rewrite lookahead; set lookahead 0 to disable */
85 
86 /* misc. configuration; don't change unless you know what you're doing */
87 #define UDF_READWRITE_LINE_LENGTH	32	/* DONT change this! 32 sectors for CD-RW/DVD-RW fixed packets */
88 #define UDF_READWRITE_ALL_PRESENT	0xffffffff
89 
90 #define UDF_INODE_HASHBITS 	10
91 #define UDF_INODE_HASHSIZE	(1<<UDF_INODE_HASHBITS)
92 #define UDF_INODE_HASHMASK	(UDF_INODE_HASHSIZE - 1)
93 
94 #define UDF_BUFCACHE_HASHBITS	13
95 #define UDF_BUFCACHE_HASHSIZE	(1<<UDF_BUFCACHE_HASHBITS)
96 #define UDF_BUFCACHE_HASHMASK	(UDF_BUFCACHE_HASHSIZE - 1)
97 
98 #define UDF_BUFCACHE_IDLE_SECS	15	/* chosen... but preferably before the device spins down (!) */
99 #define UDF_LRU_METADATA_MIN 	(100 * UDF_READWRITE_LINE_LENGTH)
100 #define UDF_LRU_METADATA_MAX	(150 * UDF_READWRITE_LINE_LENGTH)
101 #define UDF_LRU_DATA_MIN	(100 * UDF_READWRITE_LINE_LENGTH)
102 #define UDF_LRU_DATA_MAX	(300 * UDF_READWRITE_LINE_LENGTH)
103 
104 /* end of Configuration */
105 
106 
107 #if 1
108 #	define UDF_VERBOSE(op)			if (udf_verbose) { op; }
109 #	define UDF_VERBOSE_LEVEL(level, op)	if (udf_verbose >= (level)) { op; }
110 #	define UDF_VERBOSE_TABLES(op)		UDF_VERBOSE_LEVEL(UDF_VERBLEV_TABLES, op)
111 #	define UDF_VERBOSE_MAX(op)		UDF_VERBOSE_LEVEL(UDF_VERBLEV_MAX, op)
112 #else
113 #	define UDF_VERBOSE(op)
114 #	define UDF_VERBOSE_LEVEL(level, op)
115 #	define UDF_VERBOSE_TABLES(op)
116 #	define UDF_VERBOSE_MAX(op)
117 #endif
118 
119 
120 #define UDF_MUTEX(name) struct { \
121 		pthread_mutex_t mutex;\
122 		int locked;\
123 		char *status;\
124 		char *file;\
125 		int line;\
126 	} name
127 
128 #define UDF_MUTEX_INIT(name) { \
129 		pthread_mutex_init(&(name)->mutex, 0); \
130 		(name)->locked = 0; \
131 		(name)->status = "initialised as " #name;\
132 		(name)->file   = __FILE__;\
133 		(name)->line   = __LINE__;\
134 	}
135 
136 #define UDF_MUTEX_LOCK(name) { \
137 		if (0 && (name)->locked) printf("Waiting for lock " #name " at line %d of file %s marked %s in %s at line %d\n", __LINE__, __FILE__, (name)->status, (name)->file, (name)->line);\
138 		pthread_mutex_lock(&(name)->mutex);\
139 		(name)->locked = 1; \
140 		(name)->status = "locked as " #name;\
141 		(name)->file   = __FILE__;\
142 		(name)->line   = __LINE__;\
143 	}
144 
145 #define UDF_MUTEX_TRYLOCK(name) { \
146 		if (0) printf("Trying lock " #name " at line %d of file %s marked %s in %s at line %d\n", __LINE__, __FILE__, (name)->status, (name)->file, (name)->line);\
147 		if (pthread_mutex_trylock(&(name)->mutex) != EBUSY) {\
148 			(name)->locked = 1;\
149 			(name)->status = "locked as " #name;\
150 			(name)->file   = __FILE__;\
151 			(name)->line   = __LINE__;\
152 		};\
153 	}
154 
155 #define UDF_MUTEX_UNLOCK(name) { \
156 		if (0 && !(name)->locked) printf("Unlocking lock " #name " at line %d of file %s marked %s in %s at line %d\n", __LINE__, __FILE__, (name)->status, (name)->file, (name)->line);\
157 		(name)->locked = 0; \
158 		(name)->status = "unlocked as " #name;\
159 		(name)->file   = __FILE__;\
160 		(name)->line   = __LINE__;\
161 		pthread_mutex_unlock(&(name)->mutex);\
162 	}
163 
164 
165 /* Predefines */
166 struct udf_node;
167 struct udf_mountpoint;
168 
169 #include "osta.h"
170 #include "ecma167-udf.h"
171 #include "queue.h"
172 
173 #include "udf_discop.h"
174 #include "udf_unix.h"
175 #include "uio.h"
176 #include <pthread.h>
177 
178 
179 /*---------------------------------------------------------------------*/
180 
181 /*
182  * Provides :: write action -> signal written OK or signal write error
183  * NOTE: not used anymore but kept for convenience when write error resolution
184  * is build.
185  */
186 struct udf_wrcallback;
187 typedef void (udf_wrcallback_func)(int reason, struct udf_wrcallback *wrcallback, int error, uint8_t *sectordata);
188 
189 struct udf_wrcallback {
190 	udf_wrcallback_func	*function;
191 	struct udf_buf 		*udf_buf;		/* associated buffer */
192 	struct udf_node		*udf_node;		/* associated vnode  */
193 	uint32_t		 flags;			/* some reserved flags but other bits are OK			*/
194 };
195 #define UDF_WRCALLBACK_REASON_PENDING	0
196 #define UDF_WRCALLBACK_REASON_ANULATE	1
197 #define UDF_WRCALLBACK_REASON_WRITTEN	2
198 #define UDF_WRCALLBACK_FLAG_DESCRIPTOR	(1<<0)
199 #define UDF_WRCALLBACK_FLAG_BUFFER	(1<<1)
200 
201 
202 /*
203  * Provides :: ``allocentry'' an ordered list of allocation extents
204  *
205  */
206 
207 struct udf_allocentry {
208 	uint32_t		 len;
209 	uint32_t		 lb_num;
210 	uint16_t		 vpart_num;
211 	uint8_t			 flags;
212 
213 	TAILQ_ENTRY(udf_allocentry) next_alloc;
214 };
215 #define UDF_SPACE_ALLOCATED              0
216 #define UDF_SPACE_FREED                  1
217 #define UDF_SPACE_ALLOCATED_BUT_NOT_USED 1
218 #define UDF_SPACE_FREE                   2
219 #define UDF_SPACE_REDIRECT               3
220 
221 
222 TAILQ_HEAD(udf_alloc_entries, udf_allocentry);
223 
224 
225 /*
226  * Provides :: ``inode'' or rather filing system dependent v_data node linked under vnode structure
227  *
228  */
229 
230 struct udf_node {
231 	struct udf_mountpoint	*mountpoint;		/* foreign; provides logvol and fileset			*/
232 	struct udf_log_vol	*udf_log_vol;		/* foreign; backup if its not associated to mountpoint	*/
233 
234 	int			 dirty;			/* flags if (ext)fentry needs to be synced (safeguard)	*/
235 	int			 hold;			/* node is on hold i.e. don't recycle nor its buffers	*/
236 
237 	ino_t			 hashkey;		/* for hashing to lookup inode by vpart & lbnum		*/
238 	struct stat		 stat;			/* holds unix file attributes/filestats			*/
239 
240 	struct udf_alloc_entries dscr_allocs;		/* where my complete descriptor space is located	*/
241 
242 	uint8_t			 udf_filetype;		/* filetype of this node; raw, block, char, softlink... */
243 	uint8_t			 udf_filechar;		/* udf file characteristics (vis, meta, ...		*/
244 	uint16_t		 serial_num;		/* serial number of this descriptor on disc		*/
245 	uint16_t		 file_version_num;	/* file version number of this descriptor on disc	*/
246 
247 	uint16_t		 udf_icbtag_flags;	/* serial, setuid, setguid, stickybit etc		*/
248 	uint16_t		 link_cnt;		/* how many FID's are linked to this (ext)fentry	*/
249 	uint64_t		 unique_id;		/* unique file ID					*/
250 
251 	/* extended attributes and subfiles */
252 	struct udf_alloc_entry	*extattrfile_icb;	/* associated extended attribute file			*/
253 	struct udf_alloc_entry	*streamdir_icb;		/* associated streamdir					*/
254 
255 	/* internal in-node storage of extended attributes copy. */
256 	uint8_t			*extended_attr;
257 	uint32_t		 extended_attr_len;
258 
259 	/* internal in-node storage of data copy */
260 	uint8_t		 	*intern_data;		/* descriptor internal data				*/
261 	uint32_t		 intern_len;		/* length of descriptor internal data			*/
262 	uint32_t		 intern_free;		/* free space amount in the descriptor besides extattr.	*/
263 
264 	/* extents of discspace that make up this file/directory */
265 	uint32_t		 addr_type;		/* storage type of allocation descriptors		*/
266 	uint32_t		 icb_len;		/* length of an icb descriptor				*/
267 	UDF_MUTEX(alloc_mutex);
268 	struct udf_alloc_entries alloc_entries;
269 
270 	/* all associated vn_bufs for this node */
271 	UDF_MUTEX(buf_mutex);
272 	struct udf_buf_queue	 vn_bufs;
273 
274 	uint32_t		 v_numoutput;
275 
276 	/* dir hasing */
277 	struct dirhash		*dir_hash;
278 
279 	/* lists */
280 	TAILQ_ENTRY(udf_node)	 next_dirty;		/* next in dirty node list */
281 	LIST_ENTRY(udf_node)	 next_node;		/* next in hash node list */
282 };
283 
284 TAILQ_HEAD(udf_node_list, udf_node);
285 
286 
287 /*---------------------------------------------------------------------*/
288 
289 
290 /*
291  * Provides :: mountpoint -> fileset descriptor and logical volume
292  *
293  */
294 struct udf_mountpoint {
295 	char			*mount_name;		/* identifier	*/
296 	struct udf_log_vol	*udf_log_vol;		/* foreign	*/
297 	struct fileset_desc	*fileset_desc;		/* fileset belonging to this mountpoint	*/
298 
299 	struct udf_node		*rootdir_node;
300 	struct udf_node		*streamdir_node;
301 
302 	int			 writable;		/* flags if its a writable fileset	*/
303 
304 	SLIST_ENTRY(udf_mountpoint) all_next;		/* for overall mountpoint list		*/
305 	SLIST_ENTRY(udf_mountpoint) logvol_next;	/* for list of mountpoints in a logvol	*/
306 };
307 
308 
309 /*
310  * Provides :: logvol_partition -> volumeset physical partition
311  */
312 struct udf_part_mapping {
313 	uint32_t		  udf_part_mapping_type;
314 	uint32_t		  vol_seq_num;
315 	uint32_t		  udf_virt_part_num;
316 	uint32_t		  udf_phys_part_num;
317 	union  udf_pmap		 *udf_pmap;		/* foreign	*/
318 
319 	int			  data_writable;	/* flags if its suited for data */
320 	int			  metadata_writable;	/* flags if its for meta-data	*/
321 
322 	/* supporting tables */
323 	struct udf_sparing_table *sparing_table;
324 
325 	/* virtual space */
326 	struct udf_node		 *vat_udf_node;
327 	struct udf_vat		 *vat;
328 	uint8_t			 *vat_translation;
329 	uint32_t		  vat_entries;
330 	uint32_t		  vat_length;
331 
332 	/* needs to be updated; metadata partition disabled for now */
333 	struct udf_node		 *meta_file;
334 	struct udf_node		 *meta_mirror_file;
335 	struct udf_node		 *meta_bitmap_file;
336 
337 	SLIST_ENTRY(udf_part_mapping) next_mapping;	/* for list of partition mappings */
338 };
339 #define UDF_PART_MAPPING_ERROR     0
340 #define UDF_PART_MAPPING_PHYSICAL  1
341 #define UDF_PART_MAPPING_VIRTUAL   2
342 #define UDF_PART_MAPPING_SPARABLE  3
343 #define UDF_PART_MAPPING_META      4
344 #define UDF_PART_MAPPING_PSEUDO_RW 5
345 
346 
347 /*
348  * Provides :: log_vol -> ...
349  *          :: MOUNTPOINTS :)
350  */
351 struct udf_log_vol {
352 	int			 broken;
353 
354 	/* primary volume this logical volume is recorded on */
355 	struct udf_pri_vol 	*primary;		/* foreign */
356 
357 	/* logical volume info */
358 	struct logvol_desc	*log_vol;
359 	uint32_t		 lb_size;		/* constant over logvol in Ecma 167 */
360 	uint32_t		 sector_size;		/* constant over logvol in Ecma 167 */
361 
362 	/* logical volume integrity/VAT information */
363 	uint32_t		 logvol_state;		/* maintained */
364 	uint16_t		 integrity_serial;
365 	uint32_t		 min_udf_readver;
366 	uint32_t		 min_udf_writever;
367 	uint32_t		 max_udf_writever;
368 	uint32_t		 num_files;		/* maintained */
369 	uint32_t		 num_directories;	/* maintained */
370 	uint64_t		 next_unique_id;	/* maintained */
371 
372 	int			 writable;		/* flags if its writable */
373 
374 	/* dirty nodes administration */
375 	UDF_MUTEX(dirty_nodes_mutex);
376 	struct udf_node_list	dirty_nodes;
377 
378 	/* hash table to lookup ino_t -> udf_node */
379 	LIST_HEAD(inodes, udf_node) udf_nodes[UDF_INODE_HASHSIZE];
380 
381 	/* estimated free space summation; from logvol integrity */
382 	uint64_t		 total_space;
383 	uint64_t		 free_space;
384 	uint64_t		 await_alloc_space;
385 
386 	/* consisting of */
387 	uint32_t		 data_vpart, metadata_vpart;
388 
389 	uint32_t		 num_mountpoints;	/* display only */
390 	SLIST_HEAD(mountpoints_list, udf_mountpoint) mountpoints;		/* list of mountables in logvol */
391 
392 	uint32_t		 num_part_mappings;	/* display only */
393 	SLIST_HEAD(part_mappings_list, udf_part_mapping) part_mappings;		/* list of partition mappings   */
394 
395 	/* next in list */
396 	SLIST_ENTRY(udf_log_vol) next_logvol;		/* for list of logical volumes in a primary volume */
397 };
398 
399 
400 /*
401  * Provides :: pri_vol -> [log_vol], [part],[ ...]
402  *          :: { volumeset -> [pri_vols] }
403  */
404 struct udf_pri_vol {
405 	struct pri_vol_desc	*pri_vol;
406 	struct udf_session 	*udf_session;
407 
408 	struct impvol_desc	*implemation;		/* most likely reduntant */
409 	struct udf_volumeset	*volumeset;		/* foreign ; nesissary? */
410 	struct unalloc_sp_desc	*unallocated;
411 
412 	/* associated logical volumes */
413 	SLIST_HEAD(logvols, udf_log_vol) log_vols;	/* list of associated logical volumes */
414 
415 	STAILQ_ENTRY(udf_pri_vol) next_primary;		/* for primary list in volumeset */
416 };
417 
418 
419 /*
420  * Provides :: partion -> [partition info, session]
421  */
422 struct udf_partition {
423 	struct part_desc	 *partition;
424 	struct udf_session	 *udf_session;		/* foreign */
425 
426 	uint64_t		  part_offset;
427 	uint64_t		  part_length;
428 
429 	UDF_MUTEX(partition_space_mutex);		/* MUTEX for unalloc and freed space */
430 	uint64_t		  free_unalloc_space;
431 	struct udf_alloc_entries  unalloc_space_queue;	/* authorative */
432 	struct space_bitmap_desc *unalloc_space_bitmap;	/* placeholder! does NOT have to be up-to-date */
433 
434 	uint64_t		  free_freed_space;
435 	struct udf_alloc_entries  freed_space_queue;	/* authorative */
436 	struct space_bitmap_desc *freed_space_bitmap;	/* placeholder! does NOT have to be up-to-date */
437 
438 	SLIST_ENTRY(udf_partition) next_partition;	/* for partition list in volumeset */
439 };
440 
441 
442 /*
443  * Provides :: volumeset -> [pri_vol]
444  *          :: [volumeset]
445  */
446 struct udf_volumeset {
447 	int			 obsolete;
448 	uint32_t		 max_partnum;
449 
450 	STAILQ_HEAD(primaries, udf_pri_vol) primaries;	/* linked list of primary volumes associated	*/
451 	SLIST_HEAD(parts, udf_partition)    parts;	/* linked list of partitions descriptors	*/
452 
453 	SLIST_ENTRY(udf_volumeset) next_volumeset;	/* for volumeset list */
454 };
455 
456 
457 /*
458  * Provides udf_session :: -> [(disc, anchor, tracknum)]
459  */
460 struct udf_session {
461 	struct udf_discinfo	*disc;
462 	struct anchor_vdp	 anchor;
463 
464 	uint16_t		 session_num;
465 	uint32_t		 session_offset;
466 	uint32_t		 session_length;
467 
468 	int			 writable;
469 
470 	/* physical layer read/write cache */
471 	UDF_MUTEX(session_cache_lock);
472 
473 	/* SIMPLE cache */
474 	uint32_t		 cache_line_r_start;
475 	uint32_t		 cache_line_r_present;
476 	uint8_t			*cache_line_read;
477 
478 	uint32_t		 cache_line_w_start;
479 	uint32_t		 cache_line_w_present;
480 	uint32_t		 cache_line_w_dirty;
481 	uint8_t			*cache_line_write;
482 
483 	struct udf_wrcallback	cache_write_callbacks[UDF_READWRITE_LINE_LENGTH+1];
484 
485 	STAILQ_ENTRY(udf_session) next_session;		/* sessions are added at tail to preserve order */
486 };
487 /*---------------------------------------------------------------------*/
488 
489 
490 /* exported functions */
491 extern int  udf_check_tag(union dscrptr *dscr);
492 extern int  udf_check_tag_payload(union dscrptr *dscr);
493 extern int  udf_check_tag_presence(union dscrptr *dscr, int TAG);
494 
495 extern int  udf_check_session_range(char *range);
496 
497 
498 /* XXX new kernel like interface XXX */
499 extern int  udf_read_file_part_uio(struct udf_node *udf_node, char *what, int cachehints, struct uio *data_uio);
500 extern int  udf_write_file_part_uio(struct udf_node *udf_node, char *what, int cachehints, struct uio *data_uio);
501 extern void udf_dispose_udf_node(struct udf_node *udf_node);
502 extern int  udf_getattr(struct udf_node *udf_node, struct stat *stat);
503 extern int  udf_readdir(struct udf_node *udf_node, struct uio *result_uio, int *eof_res /* int *cookies, int ncookies */);
504 //extern int  udf_lookup_name_in_dir(struct udf_node *dir_node, struct udf_node **vnode, char *name);		/* not fully VOP_LOOKUP yet */
505 extern int  udf_lookup_name_in_dir(struct udf_node *dir_node, char *name, int namelen, struct long_ad *icb_loc, struct fileid_desc *fid, int *found);
506 extern int  udf_readin_udf_node(struct udf_node *dir_node, struct long_ad *udf_icbptr, struct fileid_desc *fid, struct udf_node **res_sub_node);
507 extern int  udf_sync_udf_node(struct udf_node *udf_node, char *why);			/* writeout node */
508 extern int  udf_truncate_node(struct udf_node *udf_node, uint64_t length /* ,ioflags */);
509 extern int  udf_remove_file(struct udf_node *parent_node, struct udf_node *udf_node, char *componentname);
510 extern int  udf_remove_directory(struct udf_node *dir_node, struct udf_node *udf_node, char *componentname);
511 extern int  udf_create_file(struct udf_node *dir_node, char *componentname, struct stat *stat, struct udf_node **new_node);
512 extern int  udf_create_directory(struct udf_node *dir_node, char *componentname, struct stat *stat, struct udf_node **new_node);
513 extern int  udf_rename(struct udf_node *old_parent, struct udf_node *rename_me, char *old_name, struct udf_node *new_parent, struct udf_node *present, char *new_name);
514 extern int  udf_unlink_node(struct udf_node *udf_node);
515 
516 extern int  udf_read_session_sector(struct udf_session *udf_session, uint32_t sector, char *what, uint8_t *buffer, int prefetch_sectors, int rwflags);
517 extern int  udf_write_session_sector(struct udf_session *udf_session, uint32_t sector, char *what, uint8_t *source, int rwflags, struct udf_wrcallback *wrcallback);
518 extern int  udf_read_logvol_sector(struct udf_log_vol *udf_log_vol, uint32_t vpart_num, uint32_t lb_num, char *what, uint8_t *buffer, uint32_t prefetch_sectors, int rwflags);
519 extern int  udf_write_logvol_sector(struct udf_log_vol *udf_log_vol, uint32_t vpart_num, uint32_t lb_num, char *what, uint8_t *buffer, int rwflags, struct udf_wrcallback *wrcallback);
520 
521 /* call back */
522 extern int  udf_writeout_file_buffer(struct udf_node *udf_node, char *what, int rwflags, struct udf_buf *buf_entry);
523 
524 /* special cases like VRS */
525 extern int  udf_write_session_cache_sector(struct udf_session *udf_session, uint32_t sector, char *what, uint8_t *source, int flags, struct udf_wrcallback *wrcallback);
526 
527 /* device/disc opener, closer and read/write operations */
528 extern void udf_init(void);	/* call me first! */
529 extern int  udf_mount_disc(char *devname, char *range, uint32_t sector_size, int mnt_flags, struct udf_discinfo **disc);
530 extern int  udf_dismount_disc(struct udf_discinfo *disc);
531 extern int  udf_open_disc(char *devname, int discop_flags, struct udf_discinfo **disc);
532 extern int  udf_close_disc(struct udf_discinfo *disc);
533 extern int  udf_sync_disc(struct udf_discinfo *disc);
534 extern int  udf_sync_logvol(struct udf_log_vol *udf_log_vol);
535 extern int  udf_sync_caches(struct udf_log_vol *udf_log_vol);
536 extern int  udf_open_logvol(struct udf_log_vol *udf_log_vol);
537 extern int  udf_close_logvol(struct udf_log_vol *udf_log_vol);
538 extern int  udf_sync_logvol(struct udf_log_vol *udf_log_vol);
539 
540 
541 /* readers/writers helper functions */
542 extern int  udf_init_session_caches(struct udf_session *udf_session);
543 extern int  udf_writeout_udf_node(struct udf_node *udf_node, char *why);
544 extern int  udf_sync_space_tables(struct udf_log_vol *udf_log_vol);		/* read comment on definition */
545 
546 extern int  udf_logvol_vpart_to_partition(struct udf_log_vol *udf_log_vol, uint32_t vpart_num, struct udf_part_mapping **udf_part_mapping_ptr, struct udf_partition **udf_partition_ptr);
547 extern int  udf_vpartoff_to_sessionoff(struct udf_log_vol *udf_log_vol, struct udf_part_mapping *udf_part_mapping, struct udf_partition *udf_partition, uint64_t offset, uint64_t *ses_off, uint64_t *trans_valid_len);
548 
549 extern int  udf_read_session_descriptor(struct udf_session *udf_session, uint32_t lb_num, char *what, union dscrptr **dscr, uint32_t *length);
550 extern int  udf_read_logvol_descriptor(struct udf_log_vol *udf_log_vol, uint32_t vpart_num, uint32_t lb_num, char *what, union dscrptr **dscr, uint32_t *length);
551 
552 extern int  udf_write_session_descriptor(struct udf_session *udf_session, uint32_t lb_num, char *what, union dscrptr *dscr, struct udf_wrcallback *wrcallback);
553 extern int  udf_write_partition_descriptor(struct udf_partition *udf_partition, uint32_t lb_num, char *what, union dscrptr *dscr, struct udf_wrcallback *wrcallback);
554 extern int  udf_write_logvol_descriptor(struct udf_log_vol *udf_log_vol, uint32_t vpart_num, uint32_t lb_num, char *what, union dscrptr *dscr, struct udf_wrcallback *wrcallback);
555 
556 
557 
558 /* exported text-dump functions */
559 extern void udf_dump_volume_name(char *prefix, struct udf_log_vol *udf_log_vol);
560 extern void udf_dump_long_ad(char *prefix, struct long_ad *adr);
561 extern void udf_dump_id(char *prefix, int len, char *id, struct charspec *chsp);
562 extern void udf_to_unix_name(char *result, char *id, int len, struct charspec *chsp);
563 
564 
565 /* exported descriptor creators */
566 extern int  udf_validate_tag_sum(union dscrptr *dscr);
567 extern int  udf_validate_tag_and_crc_sums(union dscrptr *dscr);
568 extern uint64_t udf_calc_tag_malloc_size(union dscrptr *dscr, uint32_t udf_sector_size);
569 extern int udf_read_fid_stream(struct udf_node *dir_node, uint64_t *offset, struct fileid_desc *fid, struct dirent *dirent);
570 extern void udf_resync_fid_stream(uint8_t *buffer, uint32_t *fid_pos, uint32_t max_fid_pos, int *fid_found);
571 extern int  udf_create_empty_anchor_volume_descriptor(uint32_t sector_size, uint16_t dscr_ver, uint32_t main_vds_loc, uint32_t reserve_vds_loc, uint32_t length, struct anchor_vdp **vdp);
572 extern int  udf_create_empty_primary_volume_descriptor(uint32_t sector_size, uint16_t dscr_ver, uint16_t serial, char *volset_id, char *privol_name, int vds_num, int max_vol_seq, struct pri_vol_desc **dscrptr);
573 extern int  udf_create_empty_partition_descriptor(uint32_t sector_size, uint16_t dscr_ver, uint16_t serial, uint16_t part_num, uint32_t access_type, uint32_t start_loc, uint32_t part_len, uint32_t space_bitmap_size, uint32_t unalloc_space_bitmap, struct part_desc **dscrptr);
574 extern int  udf_create_empty_unallocated_space_descriptor(uint32_t sector_size, uint16_t dscr_ver, uint16_t serial, struct unalloc_sp_desc **dscrptr);
575 extern int  udf_create_empty_implementation_use_volume_descriptor(uint32_t sector_size, uint16_t dscr_ver, uint16_t serial, char *logvol_name, struct impvol_desc **dscrptr);
576 extern int  udf_create_empty_logical_volume_descriptor(uint32_t sector_size, uint16_t dscr_ver, uint16_t serial, char *logvol_name, uint32_t lb_size, uint32_t integrity_start, uint32_t integrity_length, struct logvol_desc **dscrptr);
577 extern int  udf_create_empty_space_bitmap(uint32_t sector_size, uint16_t dscr_ver, uint32_t num_lbs, struct space_bitmap_desc **dscrptr);
578 extern int  udf_create_empty_terminator_descriptor(uint32_t sector_size, uint16_t dscr_ver, struct desc_tag **tag);
579 extern int  udf_create_empty_fileset_desc(uint32_t sector_size, uint16_t dscr_ver, uint32_t fileset_num, char *logvol_name, char *fileset_name, struct fileset_desc **dscrptr);
580 extern void udf_add_physical_to_logvol(struct logvol_desc *logvol, uint16_t vol_seq_num, uint16_t phys_part_num);
581 extern void udf_derive_new_logvol_integrity(struct udf_log_vol *udf_log_vol);
582 
583 /* time related creator functions */
584 extern void udf_set_timespec_now(struct timespec *timespec);
585 extern void udf_set_timestamp_now(struct timestamp *timestamp);
586 
587 /* exported processing functions */
588 extern int  udf_proc_pri_vol(struct udf_session *udf_session, struct udf_pri_vol **current, struct pri_vol_desc *incomming);
589 extern int  udf_proc_part(struct udf_pri_vol *primary, struct udf_partition **current, struct part_desc *incomming);
590 extern int  udf_proc_log_vol(struct udf_pri_vol *primary, struct udf_log_vol ** current, struct logvol_desc *incomming);
591 extern int  udf_proc_filesetdesc(struct udf_log_vol *udf_log_vol, struct fileset_desc *incomming);
592 extern int  udf_sync_space_bitmap(struct udf_alloc_entries *queue, struct space_bitmap_desc *sbd, uint32_t lb_size);
593 
594 /* exported builders */
595 extern int  udf_init_udf_node(struct udf_mountpoint *mountpoint, struct udf_log_vol *udf_log_vol, char *what, struct udf_node **udf_nodeptr);
596 extern void udf_insert_node_in_hash(struct udf_node *udf_node);
597 extern int  udf_allocate_udf_node_on_disc(struct udf_node *udf_node);
598 extern void udf_node_mark_dirty(struct udf_node *udf_node);
599 
600 extern int  udf_allocate_lbs(struct udf_log_vol *udf_log_vol, int content, uint32_t req_lbs, char *what, uint16_t *res_vpart_num, uint32_t *res_start_lb, uint32_t *res_num_lbs);
601 extern int  udf_node_allocate_lbs(struct udf_node *udf_node, int req_lbs, uint16_t *res_vpart_num, uint32_t *res_start_lb, uint32_t *res_num_lbs);
602 
603 extern int  udf_release_lbs(struct udf_log_vol *udf_log_vol, uint16_t vpart_num, uint32_t lb_num, uint64_t size);
604 extern int  udf_node_release_extent(struct udf_node *udf_node, uint64_t from, uint64_t to);
605 extern int  udf_confirm_freespace(struct udf_log_vol *udf_log_vol, int content, uint64_t size);
606 
607 
608 extern int  udf_create_directory_entry(struct udf_node *dir_node, char *componentname, int filetype, int filechar, struct udf_node *refering, struct stat *stat, struct udf_node **new_node);
609 extern int  udf_unlink_node(struct udf_node *udf_node);
610 extern uint64_t udf_increment_unique_id(struct udf_log_vol *udf_log_vol);
611 
612 /* exported (temp) allocentries */
613 extern void udf_merge_allocentry_queue(struct udf_alloc_entries *queue, uint32_t lb_size);
614 extern int  udf_cut_allocentry_queue(struct udf_alloc_entries *queue, uint32_t lb_size, uint64_t offset);
615 extern void udf_dump_allocentry_queue(char *msg, struct udf_alloc_entries *queue, uint32_t lb_size);
616 extern int  udf_filepart_mark_extent(struct udf_node *udf_node, uint64_t data_offset, uint64_t data_length, int mark);
617 extern int  udf_splitup_allocentry_queue(struct udf_alloc_entries *queue, uint32_t lb_size, uint64_t data_offset, uint64_t data_length, struct udf_allocentry **res_firstae, struct udf_allocentry **res_lastae);
618 extern int  udf_mark_allocentry_queue(struct udf_alloc_entries *queue, uint32_t lb_size, uint64_t data_offset, uint64_t data_length, int mark, struct udf_allocentry **res_firstae, struct udf_allocentry **res_lastae);
619 extern int  udf_extent_properties(struct udf_alloc_entries *queue, uint32_t lb_size, uint64_t from, uint64_t to, int *res_all_allocated);
620 
621 /* define static list types and structures */
622 SLIST_HEAD(discslist,       udf_discinfo);
623 SLIST_HEAD(volumeset_list,  udf_volumeset);
624 SLIST_HEAD(mountables_list, udf_mountpoint);
625 
626 extern struct discslist       udf_discs_list;
627 extern struct volumeset_list  udf_volumeset_list;
628 extern struct mountables_list udf_mountables;
629 
630 
631 #endif	/* _UDF_H_ */
632 
633