1 /*- 2 * Copyright (c) 1998, 1999 Semen Ustimenko (semenu@FreeBSD.org) 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD: src/sys/fs/hpfs/hpfs.h,v 1.1 1999/12/09 19:09:58 semenu Exp $ 27 */ 28 29 /*#define HPFS_DEBUG 10*/ 30 typedef u_int32_t lsn_t; /* Logical Sector Number */ 31 typedef struct { 32 lsn_t lsn1; 33 lsn_t lsn2; 34 } rsp_t; /* Redundant Sector Pointer */ 35 typedef struct { 36 u_int32_t cnt; 37 lsn_t lsn; 38 } sptr_t; /* Storage Pointer */ 39 40 #define SUBLOCK 0x10 41 #define SUSIZE DEV_BSIZE 42 #define SPBLOCK 0x11 43 #define SPSIZE DEV_BSIZE 44 #define BMSIZE (4 * DEV_BSIZE) 45 #define HPFS_MAXFILENAME 255 46 47 #define SU_MAGIC ((u_int64_t)0xFA53E9C5F995E849ULL) 48 struct sublock { 49 u_int64_t su_magic; 50 u_int8_t su_hpfsver; 51 u_int8_t su_fnctver; 52 u_int16_t unused; 53 lsn_t su_rootfno; /* Root Fnode */ 54 u_int32_t su_btotal; /* Total blocks */ 55 u_int32_t su_badbtotal; /* Bad Sectors total */ 56 rsp_t su_bitmap; 57 rsp_t su_badbl; 58 u_long su_chkdskdate; 59 u_long su_dskoptdate; 60 u_int32_t su_dbbsz; /* Sectors in DirBlock Band */ 61 lsn_t su_dbbstart; 62 lsn_t su_dbbend; 63 lsn_t su_dbbbitmap; 64 char su_volname[0x20]; 65 lsn_t su_uidt; /* Ptr to User ID Table (8 sect) */ 66 }; 67 68 #define SP_MAGIC ((u_int64_t)0xFA5229C5F9911849ULL) 69 #define SP_DIRTY 0x0001 70 #define SP_SPDBINUSE 0x0002 71 #define SP_HFINUSE 0x0004 72 #define SP_BADSECT 0x0008 73 #define SP_BADBMBL 0x0010 74 #define SP_FASTFRMT 0x0020 75 #define SP_OLDHPFS 0x0080 76 #define SP_IDASD 0x0100 77 #define SP_RDASD 0x0200 78 #define SP_DASD 0x0400 79 #define SP_MMACTIVE 0x0800 80 #define SP_DCEACLS 0x1000 81 #define SP_DSADDIRTY 0x2000 82 struct spblock { 83 u_int64_t sp_magic; 84 u_int16_t sp_flag; 85 u_int8_t sp_mmcontf; 86 u_int8_t unused; 87 lsn_t sp_hf; /* HotFix list */ 88 u_int32_t sp_hfinuse; /* HotFixes in use */ 89 u_int32_t sp_hfavail; /* HotFixes available */ 90 u_int32_t sp_spdbavail; /* Spare DirBlocks available */ 91 u_int32_t sp_spdbmax; /* Spare DirBlocks maximum */ 92 lsn_t sp_cpi; 93 u_int32_t sp_cpinum; 94 u_int32_t sp_suchecksum; 95 u_int32_t sp_spchecksum; 96 u_int8_t reserved[0x3C]; 97 lsn_t sp_spdb[0x65]; 98 }; 99 100 #define DE_SPECIAL 0x0001 101 #define DE_ACL 0x0002 102 #define DE_DOWN 0x0004 103 #define DE_END 0x0008 104 #define DE_EALIST 0x0010 105 #define DE_EPERM 0x0020 106 #define DE_EXPLACL 0x0040 107 #define DE_NEEDEA 0x0080 108 #define DE_RONLY 0x0100 109 #define DE_HIDDEN 0x0200 110 #define DE_SYSTEM 0x0400 111 #define DE_VOLLABEL 0x0800 112 #define DE_DIR 0x1000 113 #define DE_ARCHIV 0x2000 114 #define DE_DOWNLSN(dep) (*(lsn_t *)((caddr_t)(dep) + (dep)->de_reclen - sizeof(lsn_t))) 115 #define DE_NEXTDE(dep) ((struct hpfsdirent *)((caddr_t)(dep) + (dep)->de_reclen)) 116 typedef struct hpfsdirent { 117 u_int16_t de_reclen; 118 u_int16_t de_flag; 119 lsn_t de_fnode; 120 u_long de_mtime; 121 u_int32_t de_size; 122 u_long de_atime; 123 u_long de_ctime; 124 u_int32_t de_ealen; 125 u_int8_t de_flexflag; 126 u_int8_t de_cpid; 127 u_int8_t de_namelen; 128 char de_name[1]; 129 /* ... de_flex; */ 130 /* lsn_t de_down; */ 131 } hpfsdirent_t; 132 133 #define D_BSIZE (DEV_BSIZE*4) 134 #define D_MAGIC 0x77E40AAE 135 #define D_DIRENT(dbp) ((hpfsdirent_t *)((caddr_t)dbp + sizeof(dirblk_t))) 136 #define D_DE(dbp, deoff) ((hpfsdirent_t *)((caddr_t)dbp + sizeof(dirblk_t) + (deoff))) 137 typedef struct dirblk { 138 u_int32_t d_magic; 139 u_int32_t d_freeoff; /* Offset of first free byte */ 140 u_int32_t d_chcnt; /* Change count */ 141 lsn_t d_parent; 142 lsn_t d_self; 143 } dirblk_t; 144 145 /* 146 * Allocation Block (ALBLK) 147 */ 148 #define AB_HBOFFEO 0x01 149 #define AB_FNPARENT 0x20 150 #define AB_SUGGBSCH 0x40 151 #define AB_NODES 0x80 152 #define AB_ALLEAF(abp) ((alleaf_t *)((caddr_t)(abp) + sizeof(alblk_t))) 153 #define AB_ALNODE(abp) ((alnode_t *)((caddr_t)(abp) + sizeof(alblk_t))) 154 #define AB_FREEALP(abp) ((alleaf_t *)((caddr_t)(abp) + (abp)->ab_freeoff)) 155 #define AB_FREEANP(abp) ((alnode_t *)((caddr_t)(abp) + (abp)->ab_freeoff)) 156 #define AB_LASTALP(abp) (AB_ALLEAF(abp) + (abp)->ab_busycnt - 1) 157 #define AB_LASTANP(abp) (AB_ALNODE(abp) + (abp)->ab_busycnt - 1) 158 #define AB_ADDNREC(abp, sz, n) { \ 159 (abp)->ab_busycnt += (n); \ 160 (abp)->ab_freecnt -= (n); \ 161 (abp)->ab_freeoff += (n) * (sz); \ 162 } 163 #define AB_RMNREC(abp, sz, n) { \ 164 (abp)->ab_busycnt -= (n); \ 165 (abp)->ab_freecnt += (n); \ 166 (abp)->ab_freeoff -= (n) * (sz);\ 167 } 168 #define AB_ADDAL(abp) AB_ADDNREC(abp,sizeof(alleaf_t), 1) 169 #define AB_ADDAN(abp) AB_ADDNREC(abp,sizeof(alnode_t), 1) 170 #define AB_RMAL(abp) AB_RMNREC(abp,sizeof(alleaf_t), 1) 171 #define AB_RMAN(abp) AB_RMNREC(abp,sizeof(alnode_t), 1) 172 typedef struct alblk { 173 u_int8_t ab_flag; 174 u_int8_t ab_res[3]; 175 u_int8_t ab_freecnt; 176 u_int8_t ab_busycnt; 177 u_int16_t ab_freeoff; 178 } alblk_t; 179 180 /* 181 * FNode 182 */ 183 #define FNODESIZE DEV_BSIZE 184 #define FN_MAGIC 0xF7E40AAE 185 struct fnode { 186 u_int32_t fn_magic; 187 u_int64_t fn_readhist; 188 u_int8_t fn_namelen; 189 char fn_name[0xF]; /* First 15 symbols or less */ 190 lsn_t fn_parent; 191 sptr_t fn_extacl; 192 u_int16_t fn_acllen; 193 u_int8_t fn_extaclflag; 194 u_int8_t fn_histbitcount; 195 sptr_t fn_extea; 196 u_int16_t fn_ealen; /* Len of EAs in Fnode */ 197 u_int8_t fn_exteaflag; /* EAs in exteas */ 198 u_int8_t fn_flag; 199 alblk_t fn_ab; 200 u_int8_t fn_abd[0x60]; 201 u_int32_t fn_size; 202 u_int32_t fn_reqea; 203 u_int8_t fn_uid[0x10]; 204 u_int16_t fn_intoff; 205 u_int8_t fn_1dasdthr; 206 u_int8_t fn_dasdthr; 207 u_int32_t fn_dasdlim; 208 u_int32_t fn_dasdusage; 209 u_int8_t fn_int[0x13c]; 210 }; 211 212 #define EA_NAME(eap) ((char *)(((caddr_t)(eap)) + sizeof(struct ea))) 213 struct ea { 214 u_int8_t ea_type; /* 0 - plain val */ 215 /* 1 - sptr to val */ 216 /* 3 - lsn point to AlSec, cont. val */ 217 u_int8_t ea_namelen; 218 u_int16_t ea_vallen; 219 /*u_int8_t ea_name[]; */ 220 /*u_int8_t ea_val[]; */ 221 }; 222 223 /* 224 * Allocation Block Data (ALNODE) 225 * 226 * NOTE: AlNodes are used when there are too many fragments 227 * to represent the data in the AlBlk 228 */ 229 #define AN_SET(anp,nextoff,lsn) { \ 230 (anp)->an_nextoff = (nextoff); \ 231 (anp)->an_lsn = (lsn); \ 232 } 233 typedef struct alnode { 234 u_int32_t an_nextoff; /* next node offset in blocks */ 235 lsn_t an_lsn; /* position of AlSec structure */ 236 } alnode_t; 237 238 /* 239 * Allocaion Block Data (ALLEAF) 240 * 241 * NOTE: Leaves are used to point at contiguous block of data 242 * (a fragment or an "extent"); 243 */ 244 #define AL_SET(alp,off,len,lsn) { \ 245 (alp)->al_off = (off); \ 246 (alp)->al_len = (len); \ 247 (alp)->al_lsn = (lsn); \ 248 } 249 typedef struct alleaf { 250 u_int32_t al_off; /* offset in blocks */ 251 u_int32_t al_len; /* len in blocks */ 252 lsn_t al_lsn; /* phys position */ 253 } alleaf_t; 254 255 /* 256 * Allocation Sector 257 * 258 * NOTE: AlSecs are not initialized before use, so they ussually 259 * look full of junk. Use the AlBlk tto validate the data. 260 */ 261 #define AS_MAGIC 0x37E40AAE 262 typedef struct alsec { 263 u_int32_t as_magic; 264 lsn_t as_self; 265 lsn_t as_parent; 266 alblk_t as_ab; 267 u_int8_t as_abd[0x1E0]; 268 } alsec_t; 269 270 /* 271 * Code Page structures 272 */ 273 struct cpdblk { 274 u_int16_t b_country; /* Country code */ 275 u_int16_t b_cpid; /* CP ID */ 276 u_int16_t b_dbcscnt; /* Count of DBCS ranges in CP */ 277 char b_upcase[0x80]; /* Case conversion table */ 278 u_int16_t b_dbcsrange; /* Start/End DBCS range pairs */ 279 280 }; 281 282 #define CPD_MAGIC ((u_int32_t)0x894521F7) 283 struct cpdsec { 284 u_int32_t d_magic; 285 u_int16_t d_cpcnt; /* CP Data count */ 286 u_int16_t d_cpfirst; /* Index of first CP Data */ 287 u_int32_t d_checksum[3]; /* CP Data checksumms */ 288 u_int16_t d_offset[3]; /* Offsets of CP Data blocks */ 289 struct cpdblk d_cpdblk[3]; /* Array of CP Data Blocks */ 290 }; 291 292 struct cpiblk { 293 u_int16_t b_country; /* Country code */ 294 u_int16_t b_cpid; /* CP ID */ 295 u_int32_t b_checksum; 296 lsn_t b_cpdsec; /* Pointer to CP Data Sector */ 297 u_int16_t b_vcpid; /* Volume spec. CP ID */ 298 u_int16_t b_dbcscnt; /* Count of DBCS ranges in CP */ 299 }; 300 301 #define CPI_MAGIC ((u_int32_t)0x494521F7) 302 struct cpisec { 303 u_int32_t s_magic; 304 u_int32_t s_cpicnt; /* Count of CPI's in this sector */ 305 u_int32_t s_cpifirst; /* Index of first CPI in this sector */ 306 lsn_t s_next; /* Pointer to next CPI Sector */ 307 struct cpiblk s_cpi[0x1F]; /* Array of CPI blocks */ 308 }; 309 310 struct hpfsmount { 311 struct sublock hpm_su; 312 struct spblock hpm_sp; 313 struct netexport hpm_export; 314 struct mount * hpm_mp; 315 struct vnode * hpm_devvp; 316 cdev_t hpm_dev; 317 uid_t hpm_uid; 318 gid_t hpm_gid; 319 mode_t hpm_mode; 320 321 lsn_t * hpm_bmind; 322 struct cpdblk * hpm_cpdblk; /* Array of CP Data Blocks */ 323 u_char hpm_u2d[0x80]; /* Unix to DOS Table*/ 324 u_char hpm_d2u[0x80]; /* DOS to Unix Table*/ 325 326 u_long hpm_bavail; /* Blocks available */ 327 u_long hpm_dbnum; /* Data Band number */ 328 u_int8_t * hpm_bitmap; 329 }; 330 331 #define H_HASHED 0x0001 /* Present in hash */ 332 #define H_PARVALID 0x0002 /* parent info is valid */ 333 #define H_CHANGE 0x0004 /* node date was changed */ 334 #define H_PARCHANGE 0x0008 /* parent node date was changed */ 335 #define H_INVAL 0x0010 /* Invalid node */ 336 struct hpfsnode { 337 struct lwkt_token h_interlock; 338 339 LIST_ENTRY(hpfsnode) h_hash; 340 341 struct hpfsmount *h_hpmp; 342 struct fnode h_fn; 343 struct vnode * h_vp; 344 struct vnode * h_devvp; 345 cdev_t h_dev; 346 lsn_t h_no; 347 uid_t h_uid; 348 gid_t h_gid; 349 mode_t h_mode; 350 u_int32_t h_flag; 351 352 /* parent dir information */ 353 u_long h_mtime; 354 u_long h_atime; 355 u_long h_ctime; 356 char h_name[HPFS_MAXFILENAME+1]; /* Used to speedup dirent */ 357 int h_namelen; /* lookup */ 358 }; 359 360 /* This overlays the fid structure (see <sys/mount.h>) */ 361 struct hpfid { 362 u_int16_t hpfid_len; /* Length of structure. */ 363 u_int16_t hpfid_pad; /* Force 32-bit alignment. */ 364 lsn_t hpfid_ino; /* File number (ino). */ 365 int32_t hpfid_gen; /* Generation number. */ 366 }; 367 368 #if defined(HPFS_DEBUG) 369 #define dprintf(a) kprintf a 370 #if HPFS_DEBUG > 1 371 #define ddprintf(a) kprintf a 372 #else 373 #define ddprintf(a) 374 #endif 375 #else 376 #define dprintf(a) 377 #define ddprintf(a) 378 #endif 379 #ifdef MALLOC_DECLARE 380 MALLOC_DECLARE(M_HPFSMNT); 381 MALLOC_DECLARE(M_HPFSNO); 382 #endif 383 #define VFSTOHPFS(mp) ((struct hpfsmount *)((mp)->mnt_data)) 384 #define VTOHP(v) ((struct hpfsnode *)((v)->v_data)) 385 #define HPTOV(h) ((struct vnode *)((h)->h_vp)) 386 #define FID(f) (*((lsn_t *)(f)->fid_data)) 387 #define dbtodoff(dbn) ((off_t)(dbn) << DEV_BSHIFT) 388 389 #define VOP__LOCK(a, b) vn_lock((a), (b) | LK_FAILRECLAIM) 390 #define VOP__UNLOCK(a, b) vn_unlock((a)) 391 #define VGET(a, b, c) vget((a), (b)) 392 #define VN_LOCK(a, b) vn_lock((a), (b)) 393 #define LOCKMGR(a, b) lockmgr((a), (b)) 394 395 struct vfsconf; 396 397 /* Hash routines, too small to be separate header */ 398 void hpfs_hphashinit (void); 399 int hpfs_hphash_uninit (struct vfsconf *); 400 struct hpfsnode *hpfs_hphashlookup (cdev_t, lsn_t); 401 struct hpfsnode *hpfs_hphashget (cdev_t, lsn_t); 402 struct vnode *hpfs_hphashvget (cdev_t, lsn_t); 403 void hpfs_hphashins (struct hpfsnode *); 404 void hpfs_hphashrem (struct hpfsnode *); 405 extern struct lock hpfs_hphash_lock; 406