1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * High Sierra filesystem structure definitions 23 */ 24 /* 25 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 26 * Use is subject to license terms. 27 */ 28 29 #ifndef _SYS_FS_HSFS_NODE_H 30 #define _SYS_FS_HSFS_NODE_H 31 32 #ifdef __cplusplus 33 extern "C" { 34 #endif 35 36 #include <sys/taskq.h> 37 38 struct hs_direntry { 39 uint_t ext_lbn; /* LBN of start of extent */ 40 uint_t ext_size; /* no. of data bytes in extent */ 41 struct timeval cdate; /* creation date */ 42 struct timeval mdate; /* last modification date */ 43 struct timeval adate; /* last access date */ 44 enum vtype type; /* file type */ 45 mode_t mode; /* mode and type of file (UNIX) */ 46 uint_t nlink; /* no. of links to file */ 47 uid_t uid; /* owner's user id */ 48 gid_t gid; /* owner's group id */ 49 ino64_t inode; /* inode number from rrip data */ 50 dev_t r_dev; /* major/minor device numbers */ 51 uint_t xar_prot :1; /* 1 if protection in XAR */ 52 uchar_t xar_len; /* no. of Logical blocks in XAR */ 53 uchar_t intlf_sz; /* intleaving size */ 54 uchar_t intlf_sk; /* intleaving skip factor */ 55 ushort_t sym_link_flag; /* flags for sym link */ 56 char *sym_link; /* path of sym link for readlink() */ 57 }; 58 59 struct ptable { 60 uchar_t filler[7]; /* filler */ 61 uchar_t dname_len; /* length of directory name */ 62 uchar_t dname[HS_DIR_NAMELEN+1]; /* directory name */ 63 }; 64 65 struct ptable_idx { 66 struct ptable_idx *idx_pptbl_idx; /* parent's path table index entry */ 67 struct ptable *idx_mptbl; /* path table entry for myself */ 68 ushort_t idx_nochild; /* no. of children */ 69 ushort_t idx_childid; /* directory no of first child */ 70 }; 71 72 /* 73 * hsnode structure: 74 * 75 * hs_offset, hs_ptbl_idx, base apply to VDIR type only 76 * 77 * nodeid uniquely identifies an hsnode, ISO9660 means 78 * nodeid can be very big. 79 * For directories it is the disk address of 80 * the data extent of the dir (the directory itself, 81 * ".", and ".." all point to same data extent). 82 * For non-directories, it is the disk address of the 83 * directory entry for the file; note that this does 84 * not permit hard links, as it assumes a single dir 85 * entry per file. 86 */ 87 88 struct hsnode { 89 struct hsnode *hs_hash; /* next hsnode in hash list */ 90 struct hsnode *hs_freef; /* next hsnode in free list */ 91 struct hsnode *hs_freeb; /* previous hsnode in free list */ 92 struct vnode *hs_vnode; /* the real vnode for the file */ 93 struct hs_direntry hs_dirent; /* the directory entry for this file */ 94 ino64_t hs_nodeid; /* "inode" number for hsnode */ 95 uint_t hs_dir_lbn; /* LBN of directory entry */ 96 uint_t hs_dir_off; /* offset in LBN of directory entry */ 97 struct ptable_idx *hs_ptbl_idx; /* path table index */ 98 uint_t hs_offset; /* start offset in dir for searching */ 99 long hs_mapcnt; /* mappings to file pages */ 100 uint_t hs_seq; /* sequence number */ 101 uint_t hs_flags; /* (see below) */ 102 u_offset_t hs_prev_offset; /* Last read end offset (readahead) */ 103 int hs_num_contig; /* Count of contiguous reads */ 104 int hs_ra_bytes; /* Bytes to readahead */ 105 kmutex_t hs_contents_lock; /* protects hsnode contents */ 106 /* except hs_offset */ 107 }; 108 109 /* hs_flags */ 110 #define HREF 1 /* hsnode is referenced */ 111 112 /* hs_modes */ 113 114 #define HFDIR 0040000 /* directory */ 115 #define HFREG 0100000 /* regular file */ 116 117 struct hsfid { 118 ushort_t hf_len; /* length of fid */ 119 ushort_t hf_dir_off; /* offset in LBN of directory entry */ 120 uint_t hf_dir_lbn; /* LBN of directory */ 121 uint32_t hf_ino; /* The inode number or HS_DUMMY_INO */ 122 }; 123 124 125 /* 126 * All of the fields in the hs_volume are read-only once they have been 127 * initialized. 128 */ 129 struct hs_volume { 130 ulong_t vol_size; /* no. of Logical blocks in Volume */ 131 uint_t lbn_size; /* no. of bytes in a block */ 132 uint_t lbn_shift; /* shift to convert lbn to bytes */ 133 uint_t lbn_secshift; /* shift to convert lbn to sec */ 134 uint_t lbn_maxoffset; /* max lbn-relative offset and mask */ 135 uchar_t file_struct_ver; /* version of directory structure */ 136 uid_t vol_uid; /* uid of volume */ 137 gid_t vol_gid; /* gid of volume */ 138 uint_t vol_prot; /* protection (mode) of volume */ 139 struct timeval cre_date; /* volume creation time */ 140 struct timeval mod_date; /* volume modification time */ 141 struct hs_direntry root_dir; /* dir entry for Root Directory */ 142 ushort_t ptbl_len; /* number of bytes in Path Table */ 143 uint_t ptbl_lbn; /* logical block no of Path Table */ 144 ushort_t vol_set_size; /* number of CD in this vol set */ 145 ushort_t vol_set_seq; /* the sequence number of this CD */ 146 char vol_id[32]; /* volume id in PVD */ 147 }; 148 149 /* 150 * The hsnode table is no longer fixed in size but grows 151 * and shrinks dynamically. However a cache of nodes is still maintained 152 * for efficiency. This cache size (nhsnode) is a tunable which 153 * is either specified in /etc/system or calculated as the number 154 * that will fit into the number of bytes defined by HS_HSNODESPACE (below). 155 */ 156 #define HS_HASHSIZE 32 /* hsnode hash table size */ 157 #define HS_HSNODESPACE 16384 /* approx. space used for hsnodes */ 158 159 /* 160 * We usually use the starting extent LBA for the inode numbers of files and 161 * directories. As this will not work for zero sized files, we assign a dummy 162 * inode number to all zero sized files. We use the number 16 as this is the 163 * LBA for the PVD, this number cannot be a valid starting extent LBA for a 164 * file. In case that the node number is the HS_DUMMY_INO, we use the LBA and 165 * offset of the directory entry of this file (which is what we used before 166 * we started to support correct hard links). 167 */ 168 #define HS_DUMMY_INO 16 /* dummy inode number for empty files */ 169 170 /* 171 * Hsfs I/O Scheduling parameters and data structures. 172 * Deadline for reads is set at 5000 usec. 173 */ 174 #define HSFS_READ_DEADLINE 5000 175 #define HSFS_NORMAL 0x0 176 177 /* 178 * This structure holds information for a read request that is enqueued 179 * for processing by the scheduling function. An AVL tree is used to 180 * access the read requests in a sorted manner. 181 */ 182 struct hio { 183 struct buf *bp; /* The buf for this read */ 184 struct hio *contig_chain; /* Next adjacent read if any */ 185 offset_t io_lblkno; /* Starting disk block of io */ 186 u_offset_t nblocks; /* # disk blocks */ 187 uint64_t io_timestamp; /* usec timestamp for deadline */ 188 ksema_t *sema; /* Completion flag */ 189 avl_node_t io_offset_node; /* Avl tree requirements */ 190 avl_node_t io_deadline_node; 191 }; 192 193 /* 194 * This structure holds information about all the read requests issued 195 * during a read-ahead invocation. This is then enqueued on a task-queue 196 * for processing by a background thread that takes this read-ahead to 197 * completion and cleans up. 198 */ 199 struct hio_info { 200 struct buf *bufs; /* array of bufs issued for this R/A */ 201 caddr_t *vas; /* The kmem_alloced chunk for the bufs */ 202 ksema_t *sema; /* Semaphores used in the bufs */ 203 uint_t bufsused; /* # of bufs actually used */ 204 uint_t bufcnt; /* Tot bufs allocated. */ 205 struct page *pp; /* The list of I/O locked pages */ 206 struct hsfs *fsp; /* The filesystem structure */ 207 }; 208 209 /* 210 * This is per-filesystem structure that stores toplevel data structures for 211 * the I/O scheduler. 212 */ 213 struct hsfs_queue { 214 /* 215 * A dummy hio holding the LBN of the last read processed. Easy 216 * to use in AVL_NEXT for Circular Look behavior. 217 */ 218 struct hio *next; 219 220 /* 221 * A pre-allocated buf for issuing coalesced reads. The scheduling 222 * function is mostly single threaded by necessity. 223 */ 224 struct buf *nbuf; 225 kmutex_t hsfs_queue_lock; /* Protects the AVL trees */ 226 227 /* 228 * Makes most of the scheduling function Single-threaded. 229 */ 230 kmutex_t strategy_lock; 231 avl_tree_t read_tree; /* Reads ordered by LBN */ 232 avl_tree_t deadline_tree; /* Reads ordered by timestamp */ 233 taskq_t *ra_task; /* Read-ahead Q */ 234 int max_ra_bytes; /* Max read-ahead quantum */ 235 236 /* Device Max Transfer size in DEV_BSIZE */ 237 uint_t dev_maxtransfer; 238 }; 239 240 /* 241 * High Sierra filesystem structure. 242 * There is one of these for each mounted High Sierra filesystem. 243 */ 244 enum hs_vol_type { 245 HS_VOL_TYPE_HS = 0, HS_VOL_TYPE_ISO = 1, HS_VOL_TYPE_ISO_V2 = 2, 246 HS_VOL_TYPE_JOLIET = 3 247 }; 248 #define HSFS_MAGIC 0x03095500 249 struct hsfs { 250 struct hsfs *hsfs_next; /* ptr to next entry in linked list */ 251 long hsfs_magic; /* should be HSFS_MAGIC */ 252 struct vfs *hsfs_vfs; /* vfs for this fs */ 253 struct vnode *hsfs_rootvp; /* vnode for root of filesystem */ 254 struct vnode *hsfs_devvp; /* device mounted on */ 255 enum hs_vol_type hsfs_vol_type; /* see above */ 256 struct hs_volume hsfs_vol; /* File Structure Volume Descriptor */ 257 struct ptable *hsfs_ptbl; /* pointer to incore Path Table */ 258 int hsfs_ptbl_size; /* size of incore path table */ 259 struct ptable_idx *hsfs_ptbl_idx; /* pointer to path table index */ 260 int hsfs_ptbl_idx_size; /* no. of path table index */ 261 ulong_t hsfs_ext_impl; /* ext. information bits */ 262 ushort_t hsfs_sua_off; /* the SUA offset */ 263 ushort_t hsfs_namemax; /* maximum file name length */ 264 ushort_t hsfs_namelen; /* "official" max. file name length */ 265 ulong_t hsfs_err_flags; /* ways in which fs is non-conformant */ 266 char *hsfs_fsmnt; /* name mounted on */ 267 ulong_t hsfs_flags; /* hsfs-specific mount flags */ 268 krwlock_t hsfs_hash_lock; /* protect hash table & hst_nohsnode */ 269 struct hsnode *hsfs_hash[HS_HASHSIZE]; /* head of hash lists */ 270 uint32_t hsfs_nohsnode; /* no. of allocated hsnodes */ 271 kmutex_t hsfs_free_lock; /* protects free list */ 272 struct hsnode *hsfs_free_f; /* first entry of free list */ 273 struct hsnode *hsfs_free_b; /* last entry of free list */ 274 275 /* 276 * Counters exported through kstats. 277 */ 278 uint64_t physical_read_bytes; 279 uint64_t cache_read_pages; 280 uint64_t readahead_bytes; 281 uint64_t coalesced_bytes; 282 uint64_t total_pages_requested; 283 kstat_t *hsfs_kstats; 284 285 struct hsfs_queue *hqueue; /* I/O Scheduling parameters */ 286 }; 287 288 /* 289 * Error types: bit offsets into hsfs_err_flags. 290 * Also serves as index into hsfs_error[], so must be 291 * kept in sync with that data structure. 292 */ 293 #define HSFS_ERR_TRAILING_JUNK 0 294 #define HSFS_ERR_LOWER_CASE_NM 1 295 #define HSFS_ERR_BAD_ROOT_DIR 2 296 #define HSFS_ERR_UNSUP_TYPE 3 297 #define HSFS_ERR_BAD_FILE_LEN 4 298 #define HSFS_ERR_BAD_JOLIET_FILE_LEN 5 299 #define HSFS_ERR_TRUNC_JOLIET_FILE_LEN 6 300 #define HSFS_ERR_BAD_DIR_ENTRY 7 301 #define HSFS_ERR_NEG_SUA_LEN 8 302 #define HSFS_ERR_BAD_SUA_LEN 9 303 304 #define HSFS_HAVE_LOWER_CASE(fsp) \ 305 ((fsp)->hsfs_err_flags & (1 << HSFS_ERR_LOWER_CASE_NM)) 306 307 308 /* 309 * File system parameter macros 310 */ 311 #define hs_blksize(HSFS, HSP, OFF) /* file system block size */ \ 312 ((HSP)->hs_vn.v_flag & VROOT ? \ 313 ((OFF) >= \ 314 ((HSFS)->hsfs_rdirsec & ~((HSFS)->hsfs_spcl - 1))*HS_SECSIZE ?\ 315 ((HSFS)->hsfs_rdirsec & ((HSFS)->hsfs_spcl - 1))*HS_SECSIZE :\ 316 (HSFS)->hsfs_clsize): \ 317 (HSFS)->hsfs_clsize) 318 #define hs_blkoff(OFF) /* offset within block */ \ 319 ((OFF) & (HS_SECSIZE - 1)) 320 321 /* 322 * Conversion macros 323 */ 324 #define VFS_TO_HSFS(VFSP) ((struct hsfs *)(VFSP)->vfs_data) 325 #define HSFS_TO_VFS(FSP) ((FSP)->hsfs_vfs) 326 327 #define VTOH(VP) ((struct hsnode *)(VP)->v_data) 328 #define HTOV(HP) (((HP)->hs_vnode)) 329 330 /* 331 * Convert between Logical Block Number and Sector Number. 332 */ 333 #define LBN_TO_SEC(lbn, vfsp) ((lbn)>>((struct hsfs *)((vfsp)->vfs_data))-> \ 334 hsfs_vol.lbn_secshift) 335 336 #define SEC_TO_LBN(sec, vfsp) ((sec)<<((struct hsfs *)((vfsp)->vfs_data))-> \ 337 hsfs_vol.lbn_secshift) 338 339 #define LBN_TO_BYTE(lbn, vfsp) ((lbn)<<((struct hsfs *)((vfsp)->vfs_data))-> \ 340 hsfs_vol.lbn_shift) 341 #define BYTE_TO_LBN(boff, vfsp) ((boff)>>((struct hsfs *)((vfsp)->vfs_data))-> \ 342 hsfs_vol.lbn_shift) 343 344 #ifdef __cplusplus 345 } 346 #endif 347 348 #endif /* _SYS_FS_HSFS_NODE_H */ 349