nrelease - fix/improve livecd
[dragonfly.git] / sys / vfs / 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: 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;