Annotation of src/sys/fs/udf/udf.h, Revision 1.45
1.45 ! drochner 1: /* $NetBSD: udf.h,v 1.44 2011/09/27 01:13:16 christos Exp $ */
1.1 reinoud 2:
3: /*
1.11 reinoud 4: * Copyright (c) 2006, 2008 Reinoud Zandijk
1.1 reinoud 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:
1.4 christos 29: #ifndef _FS_UDF_UDF_H_
30: #define _FS_UDF_UDF_H_
1.1 reinoud 31:
32: #include <sys/queue.h>
1.43 matt 33: #include <sys/rbtree.h>
1.1 reinoud 34: #include <sys/uio.h>
1.10 ad 35: #include <sys/mutex.h>
1.1 reinoud 36:
37: #include "udf_osta.h"
38: #include "ecma167-udf.h"
39: #include <sys/cdio.h>
1.11 reinoud 40: #include <sys/bufq.h>
41: #include <sys/disk.h>
42: #include <sys/kthread.h>
1.1 reinoud 43: #include <miscfs/genfs/genfs_node.h>
44:
45: /* debug section */
46: extern int udf_verbose;
47:
1.11 reinoud 48: /* undefine UDF_COMPLETE_DELETE to need `purge'; but purge is not implemented */
49: #define UDF_COMPLETE_DELETE
1.1 reinoud 50:
51: /* debug categories */
1.32 reinoud 52: #define UDF_DEBUG_VOLUMES 0x0000001
53: #define UDF_DEBUG_LOCKING 0x0000002
54: #define UDF_DEBUG_NODE 0x0000004
55: #define UDF_DEBUG_LOOKUP 0x0000008
56: #define UDF_DEBUG_READDIR 0x0000010
57: #define UDF_DEBUG_FIDS 0x0000020
58: #define UDF_DEBUG_DESCRIPTOR 0x0000040
59: #define UDF_DEBUG_TRANSLATE 0x0000080
60: #define UDF_DEBUG_STRATEGY 0x0000100
61: #define UDF_DEBUG_READ 0x0000200
62: #define UDF_DEBUG_WRITE 0x0000400
63: #define UDF_DEBUG_CALL 0x0000800
64: #define UDF_DEBUG_ATTR 0x0001000
65: #define UDF_DEBUG_EXTATTR 0x0002000
66: #define UDF_DEBUG_ALLOC 0x0004000
67: #define UDF_DEBUG_ADWLK 0x0008000
68: #define UDF_DEBUG_DIRHASH 0x0010000
69: #define UDF_DEBUG_NOTIMPL 0x0020000
70: #define UDF_DEBUG_SHEDULE 0x0040000
71: #define UDF_DEBUG_ECCLINE 0x0080000
72: #define UDF_DEBUG_SYNC 0x0100000
73: #define UDF_DEBUG_PARANOIA 0x0200000
74: #define UDF_DEBUG_PARANOIDADWLK 0x0400000
75: #define UDF_DEBUG_NODEDUMP 0x0800000
76: #define UDF_DEBUG_RESERVE 0x1000000
1.11 reinoud 77:
78: /* initial value of udf_verbose */
79: #define UDF_DEBUGGING 0
1.1 reinoud 80:
1.8 reinoud 81: #ifdef DEBUG
1.1 reinoud 82: #define DPRINTF(name, arg) { \
83: if (udf_verbose & UDF_DEBUG_##name) {\
84: printf arg;\
85: };\
86: }
87: #define DPRINTFIF(name, cond, arg) { \
88: if (udf_verbose & UDF_DEBUG_##name) { \
89: if (cond) printf arg;\
90: };\
91: }
92: #else
93: #define DPRINTF(name, arg) {}
94: #define DPRINTFIF(name, cond, arg) {}
95: #endif
96:
97:
98: /* constants to identify what kind of identifier we are dealing with */
99: #define UDF_REGID_DOMAIN 1
100: #define UDF_REGID_UDF 2
101: #define UDF_REGID_IMPLEMENTATION 3
102: #define UDF_REGID_APPLICATION 4
103: #define UDF_REGID_NAME 99
104:
105:
106: /* DON'T change these: they identify 13thmonkey's UDF implementation */
107: #define APP_NAME "*NetBSD UDF"
1.11 reinoud 108: #define APP_VERSION_MAIN 0
1.33 reinoud 109: #define APP_VERSION_SUB 5
1.11 reinoud 110: #define IMPL_NAME "*NetBSD kernel UDF"
1.1 reinoud 111:
112:
113: /* Configuration values */
114: #define UDF_INODE_HASHBITS 10
115: #define UDF_INODE_HASHSIZE (1<<UDF_INODE_HASHBITS)
116: #define UDF_INODE_HASHMASK (UDF_INODE_HASHSIZE - 1)
1.11 reinoud 117: #define UDF_ECCBUF_HASHBITS 10
118: #define UDF_ECCBUF_HASHSIZE (1<<UDF_ECCBUF_HASHBITS)
119: #define UDF_ECCBUF_HASHMASK (UDF_ECCBUF_HASHSIZE -1)
120:
1.28 reinoud 121: #define UDF_ECCLINE_MAXFREE 5 /* picked, needs calculation */
1.35 reinoud 122: #define UDF_ECCLINE_MAXBUSY 100 /* picked, needs calculation */
1.11 reinoud 123:
124: #define UDF_MAX_MAPPINGS (MAXPHYS/DEV_BSIZE) /* 128 */
125: #define UDF_VAT_CHUNKSIZE (64*1024) /* picked */
126: #define UDF_SYMLINKBUFLEN (64*1024) /* picked */
1.1 reinoud 127:
1.34 reinoud 128: #define UDF_DISC_SLACK (128) /* picked, at least 64 kb or 128 */
1.30 reinoud 129: #define UDF_ISO_VRS_SIZE (32*2048) /* 32 ISO `sectors' */
130:
1.1 reinoud 131:
132: /* structure space */
133: #define UDF_ANCHORS 4 /* 256, 512, N-256, N */
134: #define UDF_PARTITIONS 4 /* overkill */
1.11 reinoud 135: #define UDF_PMAPS 5 /* overkill */
136: #define UDF_LVDINT_SEGMENTS 100 /* big overkill */
137: #define UDF_LVINT_LOSSAGE 4 /* lose 2 openings */
1.13 reinoud 138: #define UDF_MAX_ALLOC_EXTENTS 50 /* overkill */
1.1 reinoud 139:
140:
141: /* constants */
1.44 christos 142: #define UDF_MAXNAMLEN 255 /* as per SPEC */
1.1 reinoud 143: #define UDF_TRANS_ZERO ((uint64_t) -1)
144: #define UDF_TRANS_UNMAPPED ((uint64_t) -2)
145: #define UDF_TRANS_INTERN ((uint64_t) -3)
146: #define UDF_MAX_SECTOR ((uint64_t) -10) /* high water mark */
147:
148:
1.11 reinoud 149: /* RW content hint for allocation and other purposes */
1.30 reinoud 150: #define UDF_C_ABSOLUTE 0 /* blob to write at absolute */
1.24 reinoud 151: #define UDF_C_PROCESSED 0 /* not relevant */
152: #define UDF_C_USERDATA 1 /* all but userdata is metadata */
153: #define UDF_C_DSCR 2 /* update sectornr and CRC */
1.30 reinoud 154: #define UDF_C_FLOAT_DSCR 3 /* update sectornr and CRC; sequential */
155: #define UDF_C_NODE 4 /* file/dir node, update sectornr and CRC */
156: #define UDF_C_FIDS 5 /* update all contained fids */
157: #define UDF_C_METADATA_SBM 6 /* space bitmap, update sectornr and CRC */
158: #define UDF_C_EXTATTRS 7 /* dunno what to do yet */
1.11 reinoud 159:
160: /* use unused b_freelistindex for our UDF_C_TYPE */
161: #define b_udf_c_type b_freelistindex
162:
163:
164: /* virtual to physical mapping types */
165: #define UDF_VTOP_RAWPART UDF_PMAPS /* [0..UDF_PMAPS> are normal */
166:
167: #define UDF_VTOP_TYPE_RAW 0
168: #define UDF_VTOP_TYPE_UNKNOWN 0
169: #define UDF_VTOP_TYPE_PHYS 1
170: #define UDF_VTOP_TYPE_VIRT 2
171: #define UDF_VTOP_TYPE_SPARABLE 3
172: #define UDF_VTOP_TYPE_META 4
173:
174:
175: /* allocation strategies */
1.26 reinoud 176: #define UDF_ALLOC_INVALID 0
1.11 reinoud 177: #define UDF_ALLOC_SEQUENTIAL 1 /* linear on NWA */
178: #define UDF_ALLOC_VAT 2 /* VAT handling */
179: #define UDF_ALLOC_SPACEMAP 3 /* spacemaps */
180: #define UDF_ALLOC_METABITMAP 4 /* metadata bitmap */
181: #define UDF_ALLOC_METASEQUENTIAL 5 /* in chunks seq., nodes not seq */
182: #define UDF_ALLOC_RELAXEDSEQUENTIAL 6 /* only nodes not seq. */
183:
184:
185: /* logical volume open/close actions */
186: #define UDF_OPEN_SESSION 0x01 /* if needed writeout VRS + VDS */
187: #define UDF_CLOSE_SESSION 0x02 /* close session after writing VAT */
1.30 reinoud 188: #define UDF_FINALISE_DISC 0x04 /* close session after writing VAT */
189: #define UDF_WRITE_VAT 0x08 /* sequential VAT filesystem */
190: #define UDF_WRITE_LVINT 0x10 /* write out open lvint */
191: #define UDF_WRITE_PART_BITMAPS 0x20 /* write out partition space bitmaps */
192: #define UDF_APPENDONLY_LVINT 0x40 /* no shifting, only appending */
1.41 reinoud 193: #define UDF_WRITE_METAPART_NODES 0x80 /* write out metadata partition nodes*/
1.30 reinoud 194: #define UDFLOGVOL_BITS "\20\1OPEN_SESSION\2CLOSE_SESSION\3FINALISE_DISC" \
195: "\4WRITE_VAT\5WRITE_LVINT\6WRITE_PART_BITMAPS" \
1.41 reinoud 196: "\7APPENDONLY_LVINT\10WRITE_METAPART_NODES"
1.11 reinoud 197:
198: /* logical volume error handling actions */
199: #define UDF_UPDATE_TRACKINFO 0x01 /* update trackinfo and re-shedule */
200: #define UDF_REMAP_BLOCK 0x02 /* remap the failing block length */
201: #define UDFONERROR_BITS "\20\1UPDATE_TRACKINFO\2REMAP_BLOCK"
202:
203:
204: /* readdir cookies */
205: #define UDF_DIRCOOKIE_DOT 1
206:
207:
1.1 reinoud 208: /* malloc pools */
209: MALLOC_DECLARE(M_UDFMNT);
210: MALLOC_DECLARE(M_UDFVOLD);
211: MALLOC_DECLARE(M_UDFTEMP);
212:
1.45 ! drochner 213: extern struct pool udf_node_pool;
1.11 reinoud 214: struct udf_node;
215: struct udf_strategy;
216:
217:
218: struct udf_lvintq {
219: uint32_t start;
220: uint32_t end;
221: uint32_t pos;
222: uint32_t wpos;
223: };
224:
225:
226: struct udf_bitmap {
227: uint8_t *blob; /* allocated */
228: uint8_t *bits; /* bits themselves */
229: uint8_t *pages; /* dirty pages */
230: uint32_t max_offset; /* in bits */
231: uint32_t data_pos; /* position in data */
232: uint32_t metadata_pos; /* .. in metadata */
233: };
234:
235:
236: struct udf_strat_args {
237: struct udf_mount *ump;
238: struct udf_node *udf_node;
239: struct long_ad *icb;
240: union dscrptr *dscr;
241: struct buf *nestbuf;
242: kauth_cred_t cred;
243: int waitfor;
244: };
245:
246: struct udf_strategy {
247: int (*create_logvol_dscr) (struct udf_strat_args *args);
248: void (*free_logvol_dscr) (struct udf_strat_args *args);
249: int (*read_logvol_dscr) (struct udf_strat_args *args);
250: int (*write_logvol_dscr) (struct udf_strat_args *args);
251: void (*queuebuf) (struct udf_strat_args *args);
252: void (*discstrat_init) (struct udf_strat_args *args);
253: void (*discstrat_finish) (struct udf_strat_args *args);
254: };
255:
256: extern struct udf_strategy udf_strat_bootstrap;
257: extern struct udf_strategy udf_strat_sequential;
258: extern struct udf_strategy udf_strat_direct;
259: extern struct udf_strategy udf_strat_rmw;
1.1 reinoud 260:
261:
262: /* pre cleanup */
263: struct udf_mount {
264: struct mount *vfs_mountp;
265: struct vnode *devvp;
266: struct mmc_discinfo discinfo;
267: struct udf_args mount_args;
268:
1.11 reinoud 269: /* format descriptors */
270: kmutex_t logvol_mutex;
1.1 reinoud 271: struct anchor_vdp *anchors[UDF_ANCHORS]; /* anchors to VDS */
272: struct pri_vol_desc *primary_vol; /* identification */
273: struct logvol_desc *logical_vol; /* main mapping v->p */
274: struct unalloc_sp_desc *unallocated; /* free UDF space */
275: struct impvol_desc *implementation; /* likely reduntant */
276: struct logvol_int_desc *logvol_integrity; /* current integrity */
277: struct part_desc *partitions[UDF_PARTITIONS]; /* partitions */
1.11 reinoud 278: /* logvol_info is derived; points *into* other structures */
1.1 reinoud 279: struct udf_logvol_info *logvol_info; /* integrity descr. */
280:
281: /* fileset and root directories */
282: struct fileset_desc *fileset_desc; /* normally one */
283:
1.11 reinoud 284: /* tracing logvol integrity history */
285: struct udf_lvintq lvint_trace[UDF_LVDINT_SEGMENTS];
286: int lvopen; /* logvol actions */
287: int lvclose; /* logvol actions */
288:
1.26 reinoud 289: /* logical to physical translations */
290: int vtop[UDF_PMAPS+1]; /* vpartnr trans */
291: int vtop_tp[UDF_PMAPS+1]; /* type of trans */
292:
1.11 reinoud 293: /* disc allocation / writing method */
1.26 reinoud 294: kmutex_t allocate_mutex;
1.19 reinoud 295: int lvreadwrite; /* error handling */
1.26 reinoud 296: int vtop_alloc[UDF_PMAPS+1]; /* alloc scheme */
1.11 reinoud 297: int data_part;
1.26 reinoud 298: int node_part;
299: int fids_part;
1.1 reinoud 300:
1.11 reinoud 301: /* sequential track info */
302: struct mmc_trackinfo data_track;
303: struct mmc_trackinfo metadata_track;
304:
1.5 reinoud 305: /* VAT */
306: uint32_t first_possible_vat_location;
307: uint32_t last_possible_vat_location;
1.1 reinoud 308: uint32_t vat_entries;
309: uint32_t vat_offset; /* offset in table */
1.11 reinoud 310: uint32_t vat_last_free_lb; /* last free lb_num */
311: uint32_t vat_table_len;
312: uint32_t vat_table_alloc_len;
313: uint8_t *vat_table;
314: uint8_t *vat_pages; /* TODO */
315: struct udf_node *vat_node; /* system node */
316:
1.22 reinoud 317: /* space bitmaps for physical partitions */
1.11 reinoud 318: struct space_bitmap_desc*part_unalloc_dscr[UDF_PARTITIONS];
319: struct space_bitmap_desc*part_freed_dscr [UDF_PARTITIONS];
320: struct udf_bitmap part_unalloc_bits[UDF_PARTITIONS];
321: struct udf_bitmap part_freed_bits [UDF_PARTITIONS];
1.1 reinoud 322:
1.5 reinoud 323: /* sparable */
1.11 reinoud 324: uint32_t sparable_packet_size;
325: uint32_t packet_size;
1.1 reinoud 326: struct udf_sparing_table*sparing_table;
327:
1.5 reinoud 328: /* meta */
1.11 reinoud 329: struct udf_node *metadata_node; /* system node */
330: struct udf_node *metadatamirror_node; /* system node */
331: struct udf_node *metadatabitmap_node; /* system node */
1.25 reinoud 332: struct space_bitmap_desc*metadata_unalloc_dscr;
333: struct udf_bitmap metadata_unalloc_bits;
1.40 reinoud 334: uint32_t metadata_alloc_unit_size;
335: uint16_t metadata_alignment_unit_size;
336: uint8_t metadata_flags;
1.1 reinoud 337:
1.38 reinoud 338: /* rb tree for lookup icb to udf_node and sorted list for sync */
1.11 reinoud 339: kmutex_t ihash_lock;
340: kmutex_t get_node_lock;
1.36 reinoud 341: struct rb_tree udf_node_tree;
1.1 reinoud 342:
1.11 reinoud 343: /* syncing */
344: int syncing; /* are we syncing? */
345: kcondvar_t dirtynodes_cv; /* sleeping on sync */
346:
347: /* late allocation */
1.34 reinoud 348: int32_t uncommitted_lbs[UDF_PARTITIONS];
1.11 reinoud 349: struct long_ad *la_node_ad_cpy; /* issue buf */
350: uint64_t *la_lmapping, *la_pmapping; /* issue buf */
1.1 reinoud 351:
352: /* lists */
353: STAILQ_HEAD(udfmntpts, udf_mount) all_udf_mntpnts;
1.11 reinoud 354:
355: /* device strategy */
356: struct udf_strategy *strategy;
357: void *strategy_private;
1.1 reinoud 358: };
359:
1.11 reinoud 360: /*
361: * UDF node describing a file/directory.
362: *
363: * BUGALERT claim node_mutex before reading/writing to prevent inconsistencies !
364: */
1.1 reinoud 365: struct udf_node {
366: struct genfs_node i_gnode; /* has to be first */
367: struct vnode *vnode; /* vnode associated */
368: struct udf_mount *ump;
369:
1.11 reinoud 370: kmutex_t node_mutex;
371: kcondvar_t node_lock; /* sleeping lock */
372: char const *lock_fname;
373: int lock_lineno;
374:
1.38 reinoud 375: /* rb_node for fast lookup and fast sequential visiting */
1.36 reinoud 376: struct rb_node rbnode;
377:
1.1 reinoud 378: /* one of `fe' or `efe' can be set, not both (UDF file entry dscr.) */
379: struct file_entry *fe;
380: struct extfile_entry *efe;
1.11 reinoud 381: struct alloc_ext_entry *ext[UDF_MAX_ALLOC_EXTENTS];
382: int num_extensions;
1.1 reinoud 383:
1.11 reinoud 384: /* location found, recording location & hints */
1.1 reinoud 385: struct long_ad loc; /* FID/hash loc. */
1.11 reinoud 386: struct long_ad write_loc; /* strat 4096 loc */
1.1 reinoud 387: int needs_indirect; /* has missing indr. */
1.11 reinoud 388: struct long_ad ext_loc[UDF_MAX_ALLOC_EXTENTS];
389:
1.27 reinoud 390: struct dirhash *dir_hash;
1.1 reinoud 391:
392: /* misc */
1.11 reinoud 393: uint32_t i_flags; /* associated flags */
1.1 reinoud 394: struct lockf *lockf; /* lock list */
1.11 reinoud 395: uint32_t outstanding_bufs; /* file data */
396: uint32_t outstanding_nodedscr; /* node dscr */
1.34 reinoud 397: int32_t uncommitted_lbs; /* in UBC */
1.1 reinoud 398:
1.11 reinoud 399: /* references to associated nodes */
1.1 reinoud 400: struct udf_node *extattr;
401: struct udf_node *streamdir;
1.11 reinoud 402: struct udf_node *my_parent; /* if extended attr. */
1.1 reinoud 403: };
404:
1.11 reinoud 405:
406: /* misc. flags stored in i_flags (XXX needs cleaning up) */
1.18 reinoud 407: #define IN_ACCESS 0x0001 /* Inode access time update request */
408: #define IN_CHANGE 0x0002 /* Inode change time update request */
409: #define IN_UPDATE 0x0004 /* Inode was written to; update mtime*/
410: #define IN_MODIFY 0x0008 /* Modification time update request */
411: #define IN_MODIFIED 0x0010 /* node has been modified */
412: #define IN_ACCESSED 0x0020 /* node has been accessed */
413: #define IN_RENAME 0x0040 /* node is being renamed. XXX ?? */
414: #define IN_DELETED 0x0080 /* node is unlinked, no FID reference*/
415: #define IN_LOCKED 0x0100 /* node is locked by condvar */
416: #define IN_SYNCED 0x0200 /* node is being used by sync */
417: #define IN_CALLBACK_ULK 0x0400 /* node will be unlocked by callback */
418: #define IN_NODE_REBUILD 0x0800 /* node is rebuild */
1.11 reinoud 419:
420:
421: #define IN_FLAGBITS \
422: "\10\1IN_ACCESS\2IN_CHANGE\3IN_UPDATE\4IN_MODIFY\5IN_MODIFIED" \
423: "\6IN_ACCESSED\7IN_RENAME\10IN_DELETED\11IN_LOCKED\12IN_SYNCED" \
1.21 reinoud 424: "\13IN_CALLBACK_ULK\14IN_NODE_REBUILD"
1.11 reinoud 425:
1.3 reinoud 426: #endif /* !_FS_UDF_UDF_H_ */
CVSweb <webmaster@jp.NetBSD.org>