jfs_types.h revision 9663:ace9a2ac3683
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> 38typedef 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)) 46typedef wchar_t UniChar; 47#else 48typedef 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 59typedef int8_t s8; 60typedef uint8_t u8; 61typedef int16_t s16; 62typedef uint16_t u16; 63typedef int32_t s32; 64typedef uint32_t u32; 65typedef int64_t s64; 66typedef uint64_t u64; 67 68#ifndef _UINT_TYPES 69 /* unicode includes also define these */ 70typedef u16 uint16; 71typedef u32 uint32; 72#define _UINT_TYPES 73#endif 74 75typedef s8 int8; 76typedef u8 uint8; 77typedef s16 int16; 78typedef s32 int32; 79typedef s64 int64; 80typedef u64 uint64; 81 82#endif /* _JFS_UTILITY */ 83/* 84 * Holdovers from OS/2. Try to get away from using these altogether. 85 */ 86typedef unsigned long ULONG; 87typedef unsigned short USHORT; 88typedef unsigned char UCHAR; 89typedef void *PVOID; 90#define MAXPATHLEN 255 91 92 93/* 94 * Almost identical to Linux's timespec, but not quite 95 */ 96struct 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) 116typedef int boolean_t; 117#endif 118 119#define TRUE 1 120#define FALSE 0 121 122/* 123 * logical xd (lxd) 124 */ 125typedef 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 */ 145typedef struct { 146 s16 maxnlxd; 147 s16 nlxd; 148 lxd_t *lxd; 149} lxdlist_t; 150 151/* 152 * physical xd (pxd) 153 */ 154typedef 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 */ 175typedef struct { 176 s16 maxnpxd; 177 s16 npxd; 178 pxd_t pxd[8]; 179} pxdlist_t; 180 181 182/* 183 * data extent descriptor (dxd) 184 */ 185typedef 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 */ 212typedef struct component_name { 213 int namlen; 214 UniChar *name; 215} component_t; 216 217 218/* 219 * DASD limit information - stored in directory inode 220 */ 221typedef 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)\ 279struct {\ 280 struct type *head;\ 281 struct type *tail;\ 282} 283 284struct 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)\ 297struct {\ 298 struct type *next;\ 299 struct type *prev;\ 300} 301 302struct 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)\ 478struct {\ 479 struct type *head;\ 480} 481 482#define LIST_ENTRY(type)\ 483struct {\ 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 */ 531