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