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