xref: /dragonfly/sys/vfs/hpfs/hpfs.h (revision 7ea34faa22175b2ebd8ac26a6c025f3e54b3cb00)
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