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 2006 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 #pragma ident "%Z%%M% %I% %E% SMI" 33 34 #ifdef __cplusplus 35 extern "C" { 36 #endif 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 dev_t r_dev; /* major/minor device numbers */ 50 uint_t xar_prot :1; /* 1 if protection in XAR */ 51 uchar_t xar_len; /* no. of Logical blocks in XAR */ 52 uchar_t intlf_sz; /* intleaving size */ 53 uchar_t intlf_sk; /* intleaving skip factor */ 54 ushort_t sym_link_flag; /* flags for sym link */ 55 char *sym_link; /* path of sym link for readlink() */ 56 }; 57 58 struct ptable { 59 uchar_t filler[7]; /* filler */ 60 uchar_t dname_len; /* length of directory name */ 61 uchar_t dname[HS_DIR_NAMELEN+1]; /* directory name */ 62 }; 63 64 struct ptable_idx { 65 struct ptable_idx *idx_pptbl_idx; /* parent's path table index entry */ 66 struct ptable *idx_mptbl; /* path table entry for myself */ 67 ushort_t idx_nochild; /* no. of children */ 68 ushort_t idx_childid; /* directory no of first child */ 69 }; 70 71 /* 72 * hsnode structure: 73 * 74 * hs_offset, hs_ptbl_idx, base apply to VDIR type only 75 * 76 * nodeid uniquely identifies an hsnode, ISO9660 means 77 * nodeid can be very big. 78 * For directories it is the disk address of 79 * the data extent of the dir (the directory itself, 80 * ".", and ".." all point to same data extent). 81 * For non-directories, it is the disk address of the 82 * directory entry for the file; note that this does 83 * not permit hard links, as it assumes a single dir 84 * entry per file. 85 */ 86 87 struct hsnode { 88 struct hsnode *hs_hash; /* next hsnode in hash list */ 89 struct hsnode *hs_freef; /* next hsnode in free list */ 90 struct hsnode *hs_freeb; /* previous hsnode in free list */ 91 struct vnode *hs_vnode; /* the real vnode for the file */ 92 struct hs_direntry hs_dirent; /* the directory entry for this file */ 93 ino64_t hs_nodeid; /* "inode" number for hsnode */ 94 uint_t hs_dir_lbn; /* LBN of directory entry */ 95 uint_t hs_dir_off; /* offset in LBN of directory entry */ 96 struct ptable_idx *hs_ptbl_idx; /* path table index */ 97 uint_t hs_offset; /* start offset in dir for searching */ 98 long hs_mapcnt; /* mappings to file pages */ 99 uint_t hs_seq; /* sequence number */ 100 uint_t hs_flags; /* (see below) */ 101 kmutex_t hs_contents_lock; /* protects hsnode contents */ 102 /* except hs_offset */ 103 }; 104 105 /* hs_flags */ 106 #define HREF 1 /* hsnode is referenced */ 107 108 /* hs_modes */ 109 110 #define HFDIR 0040000 /* directory */ 111 #define HFREG 0100000 /* regular file */ 112 113 struct hsfid { 114 ushort_t hf_len; /* length of fid */ 115 ushort_t hf_dir_off; /* offset in LBN of directory entry */ 116 uint_t hf_dir_lbn; /* LBN of directory */ 117 }; 118 119 120 /* 121 * All of the fields in the hs_volume are read-only once they have been 122 * initialized. 123 */ 124 struct hs_volume { 125 ulong_t vol_size; /* no. of Logical blocks in Volume */ 126 uint_t lbn_size; /* no. of bytes in a block */ 127 uint_t lbn_shift; /* shift to convert lbn to bytes */ 128 uint_t lbn_secshift; /* shift to convert lbn to sec */ 129 uint_t lbn_maxoffset; /* max lbn-relative offset and mask */ 130 uchar_t file_struct_ver; /* version of directory structure */ 131 uid_t vol_uid; /* uid of volume */ 132 gid_t vol_gid; /* gid of volume */ 133 uint_t vol_prot; /* protection (mode) of volume */ 134 struct timeval cre_date; /* volume creation time */ 135 struct timeval mod_date; /* volume modification time */ 136 struct hs_direntry root_dir; /* dir entry for Root Directory */ 137 ushort_t ptbl_len; /* number of bytes in Path Table */ 138 uint_t ptbl_lbn; /* logical block no of Path Table */ 139 ushort_t vol_set_size; /* number of CD in this vol set */ 140 ushort_t vol_set_seq; /* the sequence number of this CD */ 141 char vol_id[32]; /* volume id in PVD */ 142 }; 143 144 /* 145 * The hsnode table is no longer fixed in size but grows 146 * and shrinks dynamically. However a cache of nodes is still maintained 147 * for efficiency. This cache size (nhsnode) is a tunable which 148 * is either specified in /etc/system or calculated as the number 149 * that will fit into the number of bytes defined by HS_HSNODESPACE (below). 150 */ 151 #define HS_HASHSIZE 32 /* hsnode hash table size */ 152 #define HS_HSNODESPACE 16384 /* approx. space used for hsnodes */ 153 154 /* 155 * High Sierra filesystem structure. 156 * There is one of these for each mounted High Sierra filesystem. 157 */ 158 enum hs_vol_type { 159 HS_VOL_TYPE_HS = 0, HS_VOL_TYPE_ISO = 1, HS_VOL_TYPE_ISO_V2 = 2, 160 HS_VOL_TYPE_JOLIET = 3 161 }; 162 #define HSFS_MAGIC 0x03095500 163 struct hsfs { 164 struct hsfs *hsfs_next; /* ptr to next entry in linked list */ 165 long hsfs_magic; /* should be HSFS_MAGIC */ 166 struct vfs *hsfs_vfs; /* vfs for this fs */ 167 struct vnode *hsfs_rootvp; /* vnode for root of filesystem */ 168 struct vnode *hsfs_devvp; /* device mounted on */ 169 enum hs_vol_type hsfs_vol_type; /* see above */ 170 struct hs_volume hsfs_vol; /* File Structure Volume Descriptor */ 171 struct ptable *hsfs_ptbl; /* pointer to incore Path Table */ 172 int hsfs_ptbl_size; /* size of incore path table */ 173 struct ptable_idx *hsfs_ptbl_idx; /* pointer to path table index */ 174 int hsfs_ptbl_idx_size; /* no. of path table index */ 175 ulong_t hsfs_ext_impl; /* ext. information bits */ 176 ushort_t hsfs_sua_off; /* the SUA offset */ 177 ushort_t hsfs_namemax; /* maximum file name length */ 178 ushort_t hsfs_namelen; /* "official" max. file name length */ 179 ulong_t hsfs_err_flags; /* ways in which fs is non-conformant */ 180 char *hsfs_fsmnt; /* name mounted on */ 181 ulong_t hsfs_flags; /* hsfs-specific mount flags */ 182 krwlock_t hsfs_hash_lock; /* protect hash table & hst_nohsnode */ 183 struct hsnode *hsfs_hash[HS_HASHSIZE]; /* head of hash lists */ 184 uint32_t hsfs_nohsnode; /* no. of allocated hsnodes */ 185 kmutex_t hsfs_free_lock; /* protects free list */ 186 struct hsnode *hsfs_free_f; /* first entry of free list */ 187 struct hsnode *hsfs_free_b; /* last entry of free list */ 188 }; 189 190 /* 191 * Error types: bit offsets into hsfs_err_flags. 192 * Also serves as index into hsfs_error[], so must be 193 * kept in sync with that data structure. 194 */ 195 #define HSFS_ERR_TRAILING_JUNK 0 196 #define HSFS_ERR_LOWER_CASE_NM 1 197 #define HSFS_ERR_BAD_ROOT_DIR 2 198 #define HSFS_ERR_UNSUP_TYPE 3 199 #define HSFS_ERR_BAD_FILE_LEN 4 200 #define HSFS_ERR_BAD_JOLIET_FILE_LEN 5 201 #define HSFS_ERR_TRUNC_JOLIET_FILE_LEN 6 202 #define HSFS_ERR_BAD_DIR_ENTRY 7 203 204 #define HSFS_HAVE_LOWER_CASE(fsp) \ 205 ((fsp)->hsfs_err_flags & (1 << HSFS_ERR_LOWER_CASE_NM)) 206 207 208 /* 209 * File system parameter macros 210 */ 211 #define hs_blksize(HSFS, HSP, OFF) /* file system block size */ \ 212 ((HSP)->hs_vn.v_flag & VROOT ? \ 213 ((OFF) >= \ 214 ((HSFS)->hsfs_rdirsec & ~((HSFS)->hsfs_spcl - 1))*HS_SECSIZE ?\ 215 ((HSFS)->hsfs_rdirsec & ((HSFS)->hsfs_spcl - 1))*HS_SECSIZE :\ 216 (HSFS)->hsfs_clsize): \ 217 (HSFS)->hsfs_clsize) 218 #define hs_blkoff(OFF) /* offset within block */ \ 219 ((OFF) & (HS_SECSIZE - 1)) 220 221 /* 222 * Conversion macros 223 */ 224 #define VFS_TO_HSFS(VFSP) ((struct hsfs *)(VFSP)->vfs_data) 225 #define HSFS_TO_VFS(FSP) ((FSP)->hsfs_vfs) 226 227 #define VTOH(VP) ((struct hsnode *)(VP)->v_data) 228 #define HTOV(HP) (((HP)->hs_vnode)) 229 230 /* 231 * Convert between Logical Block Number and Sector Number. 232 */ 233 #define LBN_TO_SEC(lbn, vfsp) ((lbn)>>((struct hsfs *)((vfsp)->vfs_data))-> \ 234 hsfs_vol.lbn_secshift) 235 236 #define SEC_TO_LBN(sec, vfsp) ((sec)<<((struct hsfs *)((vfsp)->vfs_data))-> \ 237 hsfs_vol.lbn_secshift) 238 239 #define LBN_TO_BYTE(lbn, vfsp) ((lbn)<<((struct hsfs *)((vfsp)->vfs_data))-> \ 240 hsfs_vol.lbn_shift) 241 #define BYTE_TO_LBN(boff, vfsp) ((boff)>>((struct hsfs *)((vfsp)->vfs_data))-> \ 242 hsfs_vol.lbn_shift) 243 244 /* 245 * Create a nodeid. 246 * We construct the nodeid from the location of the directory 247 * entry which points to the file. We divide by 32 to 248 * compress the range of nodeids; we know that the minimum size 249 * for an ISO9660 dirent is 34, so we will never have adjacent 250 * dirents with the same nodeid. 251 */ 252 #define HSFS_MIN_DL_SHFT 5 253 #define MAKE_NODEID(lbn, off, vfsp) \ 254 ((LBN_TO_BYTE((lbn), (vfsp)) + (off)) >> HSFS_MIN_DL_SHFT) 255 256 #ifdef __cplusplus 257 } 258 #endif 259 260 #endif /* _SYS_FS_HSFS_NODE_H */ 261