1 /*
2 * Copyright (c) International Business Machines Corp., 2000
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
12 * the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #ifndef _H_JFS_TYPES
19 #define _H_JFS_TYPES
20
21 /*
22 * jfs_types.h:
23 *
24 * basic type/utility definitions
25 *
26 * note: this header file must be the 1st include file
27 * of JFS include list in all JFS .c file.
28 */
29
30 #ifdef _JFS_UTILITY
31 /* this is defined in asm/byteorder.h for i386, but
32 * is NOT defined in asm/byteorder.h for ppc (non-kernel).
33 * Until that is changed, we'll define it here. */
34 #define __BYTEORDER_HAS_U64__
35
36 #include <sys/types.h>
37 //#include <asm/byteorder.h>
38 typedef unsigned short UniChar;
39 #else
40 #include <linux/types.h>
41 #include <linux/jfs_fs.h>
42 #include <linux/nls.h>
43
44 #ifndef _ULS_UNICHAR_DEFINED
45 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,0))
46 typedef wchar_t UniChar;
47 #else
48 typedef unsigned short UniChar;
49 #endif
50 #define _ULS_UNICHAR_DEFINED
51 #endif
52 #endif
53 /* #include "endian24.h" */
54
55 /*
56 * primitive types
57 */
58 #ifdef _JFS_UTILITY
59 typedef int8_t s8;
60 typedef uint8_t u8;
61 typedef int16_t s16;
62 typedef uint16_t u16;
63 typedef int32_t s32;
64 typedef uint32_t u32;
65 typedef int64_t s64;
66 typedef uint64_t u64;
67
68 #ifndef _UINT_TYPES
69 /* unicode includes also define these */
70 typedef u16 uint16;
71 typedef u32 uint32;
72 #define _UINT_TYPES
73 #endif
74
75 typedef s8 int8;
76 typedef u8 uint8;
77 typedef s16 int16;
78 typedef s32 int32;
79 typedef s64 int64;
80 typedef u64 uint64;
81
82 #endif /* _JFS_UTILITY */
83 /*
84 * Holdovers from OS/2. Try to get away from using these altogether.
85 */
86 typedef unsigned long ULONG;
87 typedef unsigned short USHORT;
88 typedef unsigned char UCHAR;
89 typedef void *PVOID;
90 #define MAXPATHLEN 255
91
92
93 /*
94 * Almost identical to Linux's timespec, but not quite
95 */
96 struct timestruc_t {
97 u32 tv_sec;
98 u32 tv_nsec;
99 };
100
101 /*
102 * handy
103 */
104 #undef MIN
105 #define MIN(a,b) (((a)<(b))?(a):(b))
106 #undef MAX
107 #define MAX(a,b) (((a)>(b))?(a):(b))
108 #undef ROUNDUP
109 #define ROUNDUP(x, y) ( ((x) + ((y) - 1)) & ~((y) - 1) )
110
111 #define LEFTMOSTONE 0x80000000
112 #define HIGHORDER 0x80000000u /* high order bit on */
113 #define ONES 0xffffffffu /* all bit on */
114
115 #if !defined(__sun)
116 typedef int boolean_t;
117 #endif
118
119 #define TRUE 1
120 #define FALSE 0
121
122 /*
123 * logical xd (lxd)
124 */
125 typedef struct {
126 unsigned len:24;
127 unsigned off1:8;
128 u32 off2;
129 } lxd_t;
130
131 /* lxd_t field construction */
132 #define LXDlength(lxd, length32) ( (lxd)->len = length32 )
133 #define LXDoffset(lxd, offset64)\
134 {\
135 (lxd)->off1 = ((s64)offset64) >> 32;\
136 (lxd)->off2 = (offset64) & 0xffffffff;\
137 }
138
139 /* lxd_t field extraction */
140 #define lengthLXD(lxd) ( (lxd)->len )
141 #define offsetLXD(lxd)\
142 ( ((s64)((lxd)->off1)) << 32 | (lxd)->off2 )
143
144 /* lxd list */
145 typedef struct {
146 s16 maxnlxd;
147 s16 nlxd;
148 lxd_t *lxd;
149 } lxdlist_t;
150
151 /*
152 * physical xd (pxd)
153 */
154 typedef struct {
155 unsigned len:24;
156 unsigned addr1:8;
157 u32 addr2;
158 } pxd_t;
159
160 /* xd_t field construction */
161
162 #define PXDlength(pxd, length32) ((pxd)->len = __cpu_to_le24(length32))
163 #define PXDaddress(pxd, address64)\
164 {\
165 (pxd)->addr1 = ((s64)address64) >> 32;\
166 (pxd)->addr2 = __cpu_to_le32((address64) & 0xffffffff);\
167 }
168
169 /* xd_t field extraction */
170 #define lengthPXD(pxd) __le24_to_cpu((pxd)->len)
171 #define addressPXD(pxd)\
172 ( ((s64)((pxd)->addr1)) << 32 | __le32_to_cpu((pxd)->addr2))
173
174 /* pxd list */
175 typedef struct {
176 s16 maxnpxd;
177 s16 npxd;
178 pxd_t pxd[8];
179 } pxdlist_t;
180
181
182 /*
183 * data extent descriptor (dxd)
184 */
185 typedef struct {
186 unsigned flag:8; /* 1: flags */
187 unsigned rsrvd:24; /* 3: */
188 u32 size; /* 4: size in byte */
189 unsigned len:24; /* 3: length in unit of fsblksize */
190 unsigned addr1:8; /* 1: address in unit of fsblksize */
191 u32 addr2; /* 4: address in unit of fsblksize */
192 } dxd_t; /* - 16 - */
193
194 /* dxd_t flags */
195 #define DXD_INDEX 0x80 /* B+-tree index */
196 #define DXD_INLINE 0x40 /* in-line data extent */
197 #define DXD_EXTENT 0x20 /* out-of-line single extent */
198 #define DXD_FILE 0x10 /* out-of-line file (inode) */
199 #define DXD_CORRUPT 0x08 /* Inconsistency detected */
200
201 /* dxd_t field construction
202 * Conveniently, the PXD macros work for DXD
203 */
204 #define DXDlength PXDlength
205 #define DXDaddress PXDaddress
206 #define lengthDXD lengthPXD
207 #define addressDXD addressPXD
208
209 /*
210 * directory entry argument
211 */
212 typedef struct component_name {
213 int namlen;
214 UniChar *name;
215 } component_t;
216
217
218 /*
219 * DASD limit information - stored in directory inode
220 */
221 typedef struct dasd {
222 u8 thresh; /* Alert Threshold (in percent) */
223 u8 delta; /* Alert Threshold delta (in percent) */
224 u8 rsrvd1;
225 u8 limit_hi; /* DASD limit (in logical blocks) */
226 u32 limit_lo; /* DASD limit (in logical blocks) */
227 u8 rsrvd2[3];
228 u8 used_hi; /* DASD usage (in logical blocks) */
229 u32 used_lo; /* DASD usage (in logical blocks) */
230 } dasd_t;
231
232 #define DASDLIMIT(dasdp) \
233 (((u64)((dasdp)->limit_hi) << 32) + __le32_to_cpu((dasdp)->limit_lo))
234 #define setDASDLIMIT(dasdp, limit)\
235 {\
236 (dasdp)->limit_hi = ((u64)limit) >> 32;\
237 (dasdp)->limit_lo = __cpu_to_le32(limit);\
238 }
239 #define DASDUSED(dasdp) \
240 (((u64)((dasdp)->used_hi) << 32) + __le32_to_cpu((dasdp)->used_lo))
241 #define setDASDUSED(dasdp, used)\
242 {\
243 (dasdp)->used_hi = ((u64)used) >> 32;\
244 (dasdp)->used_lo = __cpu_to_le32(used);\
245 }
246
247 /*
248 * circular doubly-linked list (cdll)
249 *
250 * A circular doubly-linked list (cdll) is anchored by a pair of pointers,
251 * one to the head of the list and the other to the tail of the list.
252 * The elements are doubly linked so that an arbitrary element can be
253 * removed without a need to traverse the list.
254 * New elements can be added to the list before or after an existing element,
255 * at the head of the list, or at the tail of the list.
256 * A circle queue may be traversed in either direction.
257 *
258 * +----------+ +-------------------------------------+
259 * | | | |
260 * +->+-----+ | +->+-----+ +->+-----+ +->+-----+ |
261 * | | h +-+ | | h +--+ | n +----+ | n +--+
262 * | +-----+ | +-----+ | +-----+ | +-----+
263 * | | t +-+ +-----+ t | | | p +--+ | | p +--+
264 * | +-----+ | | | +-----+ | +-----+ | | +-----+ |
265 * +----------+ | +-----------------------+ | |
266 * | | | |
267 * | +-------------------------+
268 * | |
269 * +----------------------------+
270 */
271 /*
272 * define header
273 *
274 * list header field definition in header element:
275 *
276 * type - type of list element struct embedding the link field
277 */
278 #define CDLL_HEADER(type)\
279 struct {\
280 struct type *head;\
281 struct type *tail;\
282 }
283
284 struct cdll_header {
285 struct cdll_header *head;
286 struct cdll_header *tail;
287 };
288
289 /*
290 * define link
291 *
292 * list link field definition in list element:
293 *
294 * type - type of parent list element struct embedding the link field
295 */
296 #define CDLL_ENTRY(type)\
297 struct {\
298 struct type *next;\
299 struct type *prev;\
300 }
301
302 struct cdll_entry {
303 struct cdll_entry *next;
304 struct cdll_entry *prev;
305 };
306
307 /*
308 * initialize header
309 *
310 * header - ptr to the header field in the header element
311 */
312 #define CDLL_INIT(header) {\
313 (header)->head = (void *)(header);\
314 (header)->tail = (void *)(header);\
315 }
316
317 /*
318 * scan list
319 *
320 * header - ptr to the header field in the header element
321 * elm - ptr to the element to be inserted
322 * field - name of the link field in the list element
323 *
324 * struct header_container *container;
325 * struct header_type *header;
326 * struct element_type *elm;
327 *
328 * header = &container->header_field;
329 * for (elm = header->head; elm != (void *)header; elm = elm->field.next)
330 */
331
332 /*
333 * insert <elm> at head of list anchored at <header>
334 *
335 * header - ptr to the header field in the header element
336 * elm - ptr to the list element to be inserted
337 * field - name of the link field in the list element
338 */
339 #define CDLL_INSERT_HEAD(header, elm, field) {\
340 (elm)->field.next = (header)->head;\
341 (elm)->field.prev = (void *)(header);\
342 if ((header)->tail == (void *)(header))\
343 (header)->tail = (elm);\
344 else\
345 (header)->head->field.prev = (elm);\
346 (header)->head = (elm);\
347 }
348
349 /*
350 * insert <elm> at tail of list anchored at <header>
351 *
352 * header - ptr to the header field in the header element
353 * elm - ptr to the list element to be inserted
354 * field - name of the link field in the list element
355 */
356 #define CDLL_INSERT_TAIL(header, elm, field) {\
357 (elm)->field.next = (void *)(header);\
358 (elm)->field.prev = (header)->tail;\
359 if ((header)->head == (void *)(header))\
360 (header)->head = (elm);\
361 else\
362 (header)->tail->field.next = (elm);\
363 (header)->tail = (elm);\
364 }
365
366 /*
367 * insert <elm> after <listelm> of list anchored at <header>
368 *
369 * header - ptr to the header field in the header element
370 * listelm - ptr to the list element at insertion point
371 * elm - ptr to the list element to be inserted
372 * field - name of the link field in the list element
373 */
374 #define CDLL_INSERT_AFTER(header, listelm, elm, field) {\
375 (elm)->field.next = (listelm)->field.next;\
376 (elm)->field.prev = (listelm);\
377 if ((listelm)->field.next == (void *)(header))\
378 (header)->tail = (elm);\
379 else\
380 (listelm)->field.next->field.prev = (elm);\
381 (listelm)->field.next = (elm);\
382 }
383
384 /*
385 * insert <elm> before <listelm> of list anchored at <header>
386 *
387 * header - ptr to the header field in the header element
388 * listelm - ptr to list element at insertion point
389 * elm - ptr to the element to be inserted
390 * field - name of the link field in the list element
391 */
392 #define CDLL_INSERT_BEFORE(header, listelm, elm, field) {\
393 (elm)->field.next = (listelm);\
394 (elm)->field.prev = (listelm)->field.prev;\
395 if ((listelm)->field.prev == (void *)(header))\
396 (header)->head = (elm);\
397 else\
398 (listelm)->field.prev->field.next = (elm);\
399 (listelm)->field.prev = (elm);\
400 }
401
402 /*
403 * remove <elm> from list anchored at <header>
404 *
405 * header - ptr to the header field in the header element
406 * elm - ptr to the list element to be removed
407 * field - name of the link field in the list element
408 */
409 #define CDLL_REMOVE(header, elm, field) {\
410 if ((elm)->field.next == (void *)(header))\
411 (header)->tail = (elm)->field.prev;\
412 else\
413 (elm)->field.next->field.prev = (elm)->field.prev;\
414 if ((elm)->field.prev == (void *)(header))\
415 (header)->head = (elm)->field.next;\
416 else\
417 (elm)->field.prev->field.next = (elm)->field.next;\
418 }
419
420 #define CDLL_MOVE_TO_HEAD(header, elm, field) {\
421 if ((elm)->field.prev != (void *)(header))\
422 {\
423 if ((elm)->field.next == (void *)(header))\
424 (header)->tail = (elm)->field.prev;\
425 else\
426 (elm)->field.next->field.prev = (elm)->field.prev;\
427 (elm)->field.prev->field.next = (elm)->field.next;\
428 (elm)->field.next = (header)->head;\
429 (elm)->field.prev = (void *)(header);\
430 (header)->head->field.prev = (elm);\
431 (header)->head = (elm);\
432 }\
433 }
434
435 #define CDLL_MOVE_TO_TAIL(header, elm, field) {\
436 if ((elm)->field.next != (void *)(header))\
437 {\
438 (elm)->field.next->field.prev = (elm)->field.prev;\
439 if ((elm)->field.prev == (void *)(header))\
440 (header)->head = (elm)->field.next;\
441 else\
442 (elm)->field.prev->field.next = (elm)->field.next;\
443 (elm)->field.next = (void *)(header);\
444 (elm)->field.prev = (header)->tail;\
445 (header)->tail->field.next = (elm);\
446 (header)->tail = (elm);\
447 }\
448 }
449
450 /*
451 * orphan list element
452 */
453 #define CDLL_SELF(elm, field)\
454 (elm)->field.next = (elm)->field.prev = (elm);
455
456
457 /*
458 * single head doubly-linked list
459 *
460 * A list is headed by a single head pointer.
461 * The elements are doubly linked so that an arbitrary element can be
462 * removed without a need to traverse the list.
463 * New elements can be added to the list at the head of the list, or
464 * after an existing element (NO insert at tail).
465 * A list may only be traversed in the forward direction.
466 * (note: the list is NULL terminated in next field.)
467 *
468 * +-----+ +->+-----+ +->+-----+ +->+-----+
469 * | NULL| | | h +--+ | n +----+ | NULL|
470 * +-----+ | +-----+ | +-----+ +-----+
471 * | | | p +--+ | p +--+
472 * | | +-----+ | +-----+ |
473 * +-----------------------+ |
474 * | |
475 * +-------------------------+
476 */
477 #define LIST_HEADER(type)\
478 struct {\
479 struct type *head;\
480 }
481
482 #define LIST_ENTRY(type)\
483 struct {\
484 struct type *next;\
485 struct type **prev;\
486 }
487
488 #define LIST_INIT(header) { (header)->head = NULL; }
489
490 /*
491 * scan list
492 *
493 * header - ptr to the header (field in header element)
494 * elm - ptr to the element to be inserted
495 * field - name of the link field in list element
496 *
497 * struct header_container *container;
498 * struct header_type *header;
499 * struct element_type *elm;
500 *
501 * header = &container->header_field;
502 * for (elm = header->head; elm; elm = elm->field.next)
503 */
504
505 #define LIST_INSERT_HEAD(header, elm, field) {\
506 if (((elm)->field.next = (header)->head) != NULL)\
507 (header)->head->field.prev = &(elm)->field.next;\
508 (header)->head = (elm);\
509 (elm)->field.prev = &(header)->head;\
510 }
511
512 #define LIST_INSERT_AFTER(listelm, elm, field) {\
513 if (((elm)->field.next = (listelm)->field.next) != NULL)\
514 (listelm)->field.next->field.prev = &(elm)->field.next;\
515 (listelm)->field.next = (elm);\
516 (elm)->field.prev = &(listelm)->field.next;\
517 }
518
519 #define LIST_REMOVE(elm, field) {\
520 if ((elm)->field.next != NULL)\
521 (elm)->field.next->field.prev = (elm)->field.prev;\
522 *(elm)->field.prev = (elm)->field.next;\
523 }
524
525 #define LIST_SELF(elm, field) {\
526 (elm)->field.next = NULL;\
527 (elm)->field.prev = &(elm)->field.next;\
528 }
529
530 #endif /* !_H_JFS_TYPES */