xref: /dragonfly/sys/vfs/hpfs/hpfs.h (revision 9dbf638f)
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.6 2003/08/20 09:56:32 rob Exp $
28  */
29 
30 /*#define HPFS_DEBUG 10*/
31 typedef u_int32_t lsn_t;	/* Logical Sector Number */
32 typedef	struct {
33 	lsn_t	lsn1;
34 	lsn_t	lsn2;
35 } rsp_t;			/* Redundant Sector Pointer */
36 typedef	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)0xFA53E9C5F995E849)
49 struct 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)0xFA5229C5F9911849)
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
83 struct 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))
117 typedef 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)))
138 typedef 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)
173 typedef 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
186 struct 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)))
214 struct 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 }
234 typedef 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 }
250 typedef 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
263 typedef 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  */
274 struct 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)
284 struct 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 
293 struct 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)
303 struct 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 
311 struct 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 */
337 struct hpfsnode {
338 	struct lock	h_lock;		/* Must be first, for std vops */
339 	struct lwkt_token h_interlock;
340 
341 	LIST_ENTRY(hpfsnode)	h_hash;
342 
343 	struct hpfsmount *h_hpmp;
344 	struct fnode 	h_fn;
345 	struct vnode *	h_vp;
346 	struct vnode *	h_devvp;
347 	dev_t		h_dev;
348 	lsn_t		h_no;
349 	uid_t          	h_uid;
350 	gid_t           h_gid;
351 	mode_t          h_mode;
352 	u_int32_t	h_flag;
353 
354 	/* parent dir information */
355 	u_long		h_mtime;
356 	u_long		h_atime;
357 	u_long		h_ctime;
358 	char 		h_name[HPFS_MAXFILENAME+1]; /* Used to speedup dirent */
359 	int 		h_namelen;		    /* lookup */
360 };
361 
362 /* This overlays the fid structure (see <sys/mount.h>) */
363 struct hpfid {
364         u_int16_t hpfid_len;     /* Length of structure. */
365         u_int16_t hpfid_pad;     /* Force 32-bit alignment. */
366         lsn_t     hpfid_ino;     /* File number (ino). */
367         int32_t   hpfid_gen;     /* Generation number. */
368 };
369 
370 #if defined(HPFS_DEBUG)
371 #define dprintf(a) printf a
372 #if HPFS_DEBUG > 1
373 #define ddprintf(a) printf a
374 #else
375 #define ddprintf(a)
376 #endif
377 #else
378 #define dprintf(a)
379 #define ddprintf(a)
380 #endif
381 
382 #if __FreeBSD_version >= 300000
383 MALLOC_DECLARE(M_HPFSMNT);
384 MALLOC_DECLARE(M_HPFSNO);
385 #endif
386 #define VFSTOHPFS(mp)	((struct hpfsmount *)((mp)->mnt_data))
387 #define	VTOHP(v)	((struct hpfsnode *)((v)->v_data))
388 #define	HPTOV(h)	((struct vnode *)((h)->h_vp))
389 #define	FID(f)		(*((lsn_t *)(f)->fid_data))
390 
391 #if defined(__NetBSD__)
392 #define MALLOC_DEFINE(a, b, c)
393 #define M_HPFSMNT	M_TEMP
394 #define M_HPFSNO	M_TEMP
395 typedef int (vop_t) (void *);
396 #define HASHINIT(a, b, c, d)	hashinit((a), (b), (c), (d))
397 #define bqrelse(bp)		brelse(bp)
398 #define VOP__LOCK(a, b, c)	VOP_LOCK((a), (b) ? LK_EXCLUSIVE : LK_SHARED)
399 #define VOP__UNLOCK(a, b, c)	VOP_UNLOCK((a), 0)
400 #define VGET(a, b, c)		vget((a), LK_EXCLUSIVE)
401 #define VN_LOCK(a, b, c)	vn_lock((a), LK_EXCLUSIVE)
402 #define	LOCKMGR(a, b, c, d)	lockmgr((a), (b), (c))
403 #else  /* defined(__FreeBSD__) */
404 #define HASHINIT(a, b, c, d)	hashinit((a), (b), (d))
405 #define VOP__LOCK(a, b, c)	VOP_LOCK((a), (b), (c))
406 #define VOP__UNLOCK(a, b, c)	VOP_UNLOCK((a), (b), (c))
407 #define VGET(a, b, c)		vget((a), (b), (c))
408 #define VN_LOCK(a, b, c)	vn_lock((a), (b), (c))
409 #define	LOCKMGR(a, b, c, d)	lockmgr((a), (b), (c), (d))
410 #endif
411 
412 extern vop_t ** hpfs_vnodeop_p;
413 
414 /* Hash routines, too small to be separate header */
415 void hpfs_hphashinit (void);
416 struct hpfsnode *hpfs_hphashlookup (dev_t, lsn_t);
417 struct hpfsnode *hpfs_hphashget (dev_t, lsn_t);
418 struct vnode *hpfs_hphashvget (dev_t, lsn_t, struct thread *);
419 void hpfs_hphashins (struct hpfsnode *);
420 void hpfs_hphashrem (struct hpfsnode *);
421 extern struct lock hpfs_hphash_lock;
422