POSIX.1-2003: Changing the group ID is permitted to a process with an
[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  * $DragonFly: src/sys/vfs/hpfs/hpfs.h,v 1.10 2004/03/01 06:33:20 dillon 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)0xFA53E9C5F995E849ULL)
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)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
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 MALLOC_DECLARE(M_HPFSMNT);
382 MALLOC_DECLARE(M_HPFSNO);
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
388 #if defined(__NetBSD__)
389 #define MALLOC_DEFINE(a, b, c)
390 #define M_HPFSMNT       M_TEMP
391 #define M_HPFSNO        M_TEMP
392 typedef int (vop_t) (void *);
393 #define HASHINIT(a, b, c, d)    hashinit((a), (b), (c), (d))
394 #define bqrelse(bp)             brelse(bp)
395 #define VOP__LOCK(a, b, c)      VOP_LOCK((a), (b) ? LK_EXCLUSIVE : LK_SHARED)
396 #define VOP__UNLOCK(a, b, c)    VOP_UNLOCK((a), 0)
397 #define VGET(a, b, c)           vget((a), LK_EXCLUSIVE)
398 #define VN_LOCK(a, b, c)        vn_lock((a), LK_EXCLUSIVE)
399 #define LOCKMGR(a, b, c, d)     lockmgr((a), (b), (c))
400 #else  /* defined(__DragonFly__) */
401 #define HASHINIT(a, b, c, d)    hashinit((a), (b), (d))
402 #define VOP__LOCK(a, b, c)      VOP_LOCK((a), NULL, (b), (c))
403 #define VOP__UNLOCK(a, b, c)    VOP_UNLOCK((a), NULL, (b), (c))
404 #define VGET(a, b, c)           vget((a), NULL, (b), (c))
405 #define VN_LOCK(a, b, c)        vn_lock((a), NULL, (b), (c))
406 #define LOCKMGR(a, b, c, d)     lockmgr((a), (b), (c), (d))
407 #endif
408
409 extern vop_t ** hpfs_vnodeop_p;
410 struct vfsconf;
411
412 /* Hash routines, too small to be separate header */
413 void hpfs_hphashinit (void);
414 int hpfs_hphash_uninit (struct vfsconf *);
415 struct hpfsnode *hpfs_hphashlookup (dev_t, lsn_t);
416 struct hpfsnode *hpfs_hphashget (dev_t, lsn_t);
417 struct vnode *hpfs_hphashvget (dev_t, lsn_t, struct thread *);
418 void hpfs_hphashins (struct hpfsnode *);
419 void hpfs_hphashrem (struct hpfsnode *);
420 extern struct lock hpfs_hphash_lock;