VFS messaging/interfacing work stage 4/99. This stage goes a long ways
[dragonfly.git] / sys / vfs / hpfs / hpfs.h
... / ...
CommitLineData
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.13 2004/08/28 19:02:14 dillon Exp $
28 */
29
30/*#define HPFS_DEBUG 10*/
31typedef u_int32_t lsn_t; /* Logical Sector Number */
32typedef struct {
33 lsn_t lsn1;
34 lsn_t lsn2;
35} rsp_t; /* Redundant Sector Pointer */
36typedef 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)0xFA53E9C5F995E849ULL)
49struct 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)0xFA5229C5F9911849ULL)
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
83struct 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))
117typedef 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)))
138typedef 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)
173typedef 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
186struct 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)))
214struct 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}
234typedef 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}
250typedef 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
263typedef 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 */
274struct 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)
284struct 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
293struct 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)
303struct 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
311struct 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 */
337struct hpfsnode {
338 struct lwkt_token h_interlock;
339
340 LIST_ENTRY(hpfsnode) h_hash;
341
342 struct hpfsmount *h_hpmp;
343 struct fnode h_fn;
344 struct vnode * h_vp;
345 struct vnode * h_devvp;
346 dev_t h_dev;
347 lsn_t h_no;
348 uid_t h_uid;
349 gid_t h_gid;
350 mode_t h_mode;
351 u_int32_t h_flag;
352
353 /* parent dir information */
354 u_long h_mtime;
355 u_long h_atime;
356 u_long h_ctime;
357 char h_name[HPFS_MAXFILENAME+1]; /* Used to speedup dirent */
358 int h_namelen; /* lookup */
359};
360
361/* This overlays the fid structure (see <sys/mount.h>) */
362struct hpfid {
363 u_int16_t hpfid_len; /* Length of structure. */
364 u_int16_t hpfid_pad; /* Force 32-bit alignment. */
365 lsn_t hpfid_ino; /* File number (ino). */
366 int32_t hpfid_gen; /* Generation number. */
367};
368
369#if defined(HPFS_DEBUG)
370#define dprintf(a) printf a
371#if HPFS_DEBUG > 1
372#define ddprintf(a) printf a
373#else
374#define ddprintf(a)
375#endif
376#else
377#define dprintf(a)
378#define ddprintf(a)
379#endif
380MALLOC_DECLARE(M_HPFSMNT);
381MALLOC_DECLARE(M_HPFSNO);
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#if defined(__NetBSD__)
388#define MALLOC_DEFINE(a, b, c)
389#define M_HPFSMNT M_TEMP
390#define M_HPFSNO M_TEMP
391typedef int (vop_t) (void *);
392#define HASHINIT(a, b, c, d) hashinit((a), (b), (c), (d))
393#define bqrelse(bp) brelse(bp)
394#define VOP__LOCK(a, b, c) VOP_LOCK((a), (b) ? LK_EXCLUSIVE : LK_SHARED)
395#define VOP__UNLOCK(a, b, c) VOP_UNLOCK((a), 0)
396#define VGET(a, b, c) vget((a), LK_EXCLUSIVE)
397#define VN_LOCK(a, b, c) vn_lock((a), LK_EXCLUSIVE)
398#define LOCKMGR(a, b, c, d) lockmgr((a), (b), (c))
399#else /* defined(__DragonFly__) */
400#define HASHINIT(a, b, c, d) hashinit((a), (b), (d))
401#define VOP__LOCK(a, b, c) VOP_LOCK((a), NULL, (b), (c))
402#define VOP__UNLOCK(a, b, c) VOP_UNLOCK((a), NULL, (b), (c))
403#define VGET(a, b, c) vget((a), NULL, (b), (c))
404#define VN_LOCK(a, b, c) vn_lock((a), NULL, (b), (c))
405#define LOCKMGR(a, b, c, d) lockmgr((a), (b), (c), (d))
406#endif
407
408struct vfsconf;
409
410/* Hash routines, too small to be separate header */
411void hpfs_hphashinit (void);
412int hpfs_hphash_uninit (struct vfsconf *);
413struct hpfsnode *hpfs_hphashlookup (dev_t, lsn_t);
414struct hpfsnode *hpfs_hphashget (dev_t, lsn_t);
415struct vnode *hpfs_hphashvget (dev_t, lsn_t, struct thread *);
416void hpfs_hphashins (struct hpfsnode *);
417void hpfs_hphashrem (struct hpfsnode *);
418extern struct lock hpfs_hphash_lock;