FreeBSD/Linux Kernel Cross Reference
sys/fs/hpfs/hpfs.h
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$
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)0xFA53E9C5F995E849)
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)0xFA5229C5F9911849)
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 mount * hpm_mp;
314 struct vnode * hpm_devvp; /* XXX: loose this, it's in hpfsmount */
315 struct g_consumer *hpm_cp;
316 struct bufobj *hpm_bo;
317 struct cdev *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_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 mtx h_interlock;
338
339 struct hpfsmount *h_hpmp;
340 struct fnode h_fn;
341 struct vnode * h_vp;
342 struct vnode * h_devvp; /* XXX: remove, hpfsmount has it */
343 struct cdev *h_dev;
344 lsn_t h_no;
345 uid_t h_uid;
346 gid_t h_gid;
347 mode_t h_mode;
348 u_int32_t h_flag;
349
350 /* parent dir information */
351 u_long h_mtime;
352 u_long h_atime;
353 u_long h_ctime;
354 char h_name[HPFS_MAXFILENAME+1]; /* Used to speedup dirent */
355 int h_namelen; /* lookup */
356 };
357
358 /* This overlays the fid structure (see <sys/mount.h>) */
359 struct hpfid {
360 u_int16_t hpfid_len; /* Length of structure. */
361 u_int16_t hpfid_pad; /* Force 32-bit alignment. */
362 lsn_t hpfid_ino; /* File number (ino). */
363 int32_t hpfid_gen; /* Generation number. */
364 };
365
366 #if defined(HPFS_DEBUG)
367 #define dprintf(a) printf a
368 #if HPFS_DEBUG > 1
369 #define ddprintf(a) printf a
370 #else
371 #define ddprintf(a)
372 #endif
373 #else
374 #define dprintf(a)
375 #define ddprintf(a)
376 #endif
377
378 #if __FreeBSD_version >= 300000
379 MALLOC_DECLARE(M_HPFSMNT);
380 MALLOC_DECLARE(M_HPFSNO);
381 #endif
382 #define VFSTOHPFS(mp) ((struct hpfsmount *)((mp)->mnt_data))
383 #define VTOHP(v) ((struct hpfsnode *)((v)->v_data))
384 #define HPTOV(h) ((struct vnode *)((h)->h_vp))
385 #define FID(f) (*((lsn_t *)(f)->fid_data))
386
387 extern struct vop_vector hpfs_vnodeops;
Cache object: 4400c11253f1f9593764c15ac7d09ee1
|