blob: 7177f2af65071f998043732c3fc80f45461dc6f5 [file] [log] [blame]
/*
* Copyright (c) International Business Machines Corp., 2000
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
* the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _H_JFS_TYPES
#define _H_JFS_TYPES
/*
* jfs_types.h:
*
* basic type/utility definitions
*
* note: this header file must be the 1st include file
* of JFS include list in all JFS .c file.
*/
#ifdef _JFS_UTILITY
/* this is defined in asm/byteorder.h for i386, but
* is NOT defined in asm/byteorder.h for ppc (non-kernel).
* Until that is changed, we'll define it here. */
#define __BYTEORDER_HAS_U64__
#include <sys/types.h>
//#include <asm/byteorder.h>
typedef unsigned short UniChar;
#else
#include <linux/types.h>
#include <linux/jfs_fs.h>
#include <linux/nls.h>
#ifndef _ULS_UNICHAR_DEFINED
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,0))
typedef wchar_t UniChar;
#else
typedef unsigned short UniChar;
#endif
#define _ULS_UNICHAR_DEFINED
#endif
#endif
/* #include "endian24.h" */
/*
* primitive types
*/
#ifdef _JFS_UTILITY
typedef int8_t s8;
typedef uint8_t u8;
typedef int16_t s16;
typedef uint16_t u16;
typedef int32_t s32;
typedef uint32_t u32;
typedef int64_t s64;
typedef uint64_t u64;
#ifndef _UINT_TYPES
/* unicode includes also define these */
typedef u16 uint16;
typedef u32 uint32;
#define _UINT_TYPES
#endif
typedef s8 int8;
typedef u8 uint8;
typedef s16 int16;
typedef s32 int32;
typedef s64 int64;
typedef u64 uint64;
#endif /* _JFS_UTILITY */
/*
* Holdovers from OS/2. Try to get away from using these altogether.
*/
typedef unsigned long ULONG;
typedef unsigned short USHORT;
typedef unsigned char UCHAR;
typedef void *PVOID;
#define MAXPATHLEN 255
/*
* Almost identical to Linux's timespec, but not quite
*/
struct timestruc_t {
u32 tv_sec;
u32 tv_nsec;
};
/*
* handy
*/
#undef MIN
#define MIN(a,b) (((a)<(b))?(a):(b))
#undef MAX
#define MAX(a,b) (((a)>(b))?(a):(b))
#undef ROUNDUP
#define ROUNDUP(x, y) ( ((x) + ((y) - 1)) & ~((y) - 1) )
#define LEFTMOSTONE 0x80000000
#define HIGHORDER 0x80000000u /* high order bit on */
#define ONES 0xffffffffu /* all bit on */
typedef int boolean_t;
#define TRUE 1
#define FALSE 0
/*
* logical xd (lxd)
*/
typedef struct {
unsigned len:24;
unsigned off1:8;
u32 off2;
} lxd_t;
/* lxd_t field construction */
#define LXDlength(lxd, length32) ( (lxd)->len = length32 )
#define LXDoffset(lxd, offset64)\
{\
(lxd)->off1 = ((s64)offset64) >> 32;\
(lxd)->off2 = (offset64) & 0xffffffff;\
}
/* lxd_t field extraction */
#define lengthLXD(lxd) ( (lxd)->len )
#define offsetLXD(lxd)\
( ((s64)((lxd)->off1)) << 32 | (lxd)->off2 )
/* lxd list */
typedef struct {
s16 maxnlxd;
s16 nlxd;
lxd_t *lxd;
} lxdlist_t;
/*
* physical xd (pxd)
*/
typedef struct {
unsigned len:24;
unsigned addr1:8;
u32 addr2;
} pxd_t;
/* xd_t field construction */
#define PXDlength(pxd, length32) ((pxd)->len = __cpu_to_le24(length32))
#define PXDaddress(pxd, address64)\
{\
(pxd)->addr1 = ((s64)address64) >> 32;\
(pxd)->addr2 = __cpu_to_le32((address64) & 0xffffffff);\
}
/* xd_t field extraction */
#define lengthPXD(pxd) __le24_to_cpu((pxd)->len)
#define addressPXD(pxd)\
( ((s64)((pxd)->addr1)) << 32 | __le32_to_cpu((pxd)->addr2))
/* pxd list */
typedef struct {
s16 maxnpxd;
s16 npxd;
pxd_t pxd[8];
} pxdlist_t;
/*
* data extent descriptor (dxd)
*/
typedef struct {
unsigned flag:8; /* 1: flags */
unsigned rsrvd:24; /* 3: */
u32 size; /* 4: size in byte */
unsigned len:24; /* 3: length in unit of fsblksize */
unsigned addr1:8; /* 1: address in unit of fsblksize */
u32 addr2; /* 4: address in unit of fsblksize */
} dxd_t; /* - 16 - */
/* dxd_t flags */
#define DXD_INDEX 0x80 /* B+-tree index */
#define DXD_INLINE 0x40 /* in-line data extent */
#define DXD_EXTENT 0x20 /* out-of-line single extent */
#define DXD_FILE 0x10 /* out-of-line file (inode) */
#define DXD_CORRUPT 0x08 /* Inconsistency detected */
/* dxd_t field construction
* Conveniently, the PXD macros work for DXD
*/
#define DXDlength PXDlength
#define DXDaddress PXDaddress
#define lengthDXD lengthPXD
#define addressDXD addressPXD
/*
* directory entry argument
*/
typedef struct component_name {
int namlen;
UniChar *name;
} component_t;
/*
* DASD limit information - stored in directory inode
*/
typedef struct dasd {
u8 thresh; /* Alert Threshold (in percent) */
u8 delta; /* Alert Threshold delta (in percent) */
u8 rsrvd1;
u8 limit_hi; /* DASD limit (in logical blocks) */
u32 limit_lo; /* DASD limit (in logical blocks) */
u8 rsrvd2[3];
u8 used_hi; /* DASD usage (in logical blocks) */
u32 used_lo; /* DASD usage (in logical blocks) */
} dasd_t;
#define DASDLIMIT(dasdp) \
(((u64)((dasdp)->limit_hi) << 32) + __le32_to_cpu((dasdp)->limit_lo))
#define setDASDLIMIT(dasdp, limit)\
{\
(dasdp)->limit_hi = ((u64)limit) >> 32;\
(dasdp)->limit_lo = __cpu_to_le32(limit);\
}
#define DASDUSED(dasdp) \
(((u64)((dasdp)->used_hi) << 32) + __le32_to_cpu((dasdp)->used_lo))
#define setDASDUSED(dasdp, used)\
{\
(dasdp)->used_hi = ((u64)used) >> 32;\
(dasdp)->used_lo = __cpu_to_le32(used);\
}
/*
* circular doubly-linked list (cdll)
*
* A circular doubly-linked list (cdll) is anchored by a pair of pointers,
* one to the head of the list and the other to the tail of the list.
* The elements are doubly linked so that an arbitrary element can be
* removed without a need to traverse the list.
* New elements can be added to the list before or after an existing element,
* at the head of the list, or at the tail of the list.
* A circle queue may be traversed in either direction.
*
* +----------+ +-------------------------------------+
* | | | |
* +->+-----+ | +->+-----+ +->+-----+ +->+-----+ |
* | | h +-+ | | h +--+ | n +----+ | n +--+
* | +-----+ | +-----+ | +-----+ | +-----+
* | | t +-+ +-----+ t | | | p +--+ | | p +--+
* | +-----+ | | | +-----+ | +-----+ | | +-----+ |
* +----------+ | +-----------------------+ | |
* | | | |
* | +-------------------------+
* | |
* +----------------------------+
*/
/*
* define header
*
* list header field definition in header element:
*
* type - type of list element struct embedding the link field
*/
#define CDLL_HEADER(type)\
struct {\
struct type *head;\
struct type *tail;\
}
struct cdll_header {
struct cdll_header *head;
struct cdll_header *tail;
};
/*
* define link
*
* list link field definition in list element:
*
* type - type of parent list element struct embedding the link field
*/
#define CDLL_ENTRY(type)\
struct {\
struct type *next;\
struct type *prev;\
}
struct cdll_entry {
struct cdll_entry *next;
struct cdll_entry *prev;
};
/*
* initialize header
*
* header - ptr to the header field in the header element
*/
#define CDLL_INIT(header) {\
(header)->head = (void *)(header);\
(header)->tail = (void *)(header);\
}
/*
* scan list
*
* header - ptr to the header field in the header element
* elm - ptr to the element to be inserted
* field - name of the link field in the list element
*
* struct header_container *container;
* struct header_type *header;
* struct element_type *elm;
*
* header = &container->header_field;
* for (elm = header->head; elm != (void *)header; elm = elm->field.next)
*/
/*
* insert <elm> at head of list anchored at <header>
*
* header - ptr to the header field in the header element
* elm - ptr to the list element to be inserted
* field - name of the link field in the list element
*/
#define CDLL_INSERT_HEAD(header, elm, field) {\
(elm)->field.next = (header)->head;\
(elm)->field.prev = (void *)(header);\
if ((header)->tail == (void *)(header))\
(header)->tail = (elm);\
else\
(header)->head->field.prev = (elm);\
(header)->head = (elm);\
}
/*
* insert <elm> at tail of list anchored at <header>
*
* header - ptr to the header field in the header element
* elm - ptr to the list element to be inserted
* field - name of the link field in the list element
*/
#define CDLL_INSERT_TAIL(header, elm, field) {\
(elm)->field.next = (void *)(header);\
(elm)->field.prev = (header)->tail;\
if ((header)->head == (void *)(header))\
(header)->head = (elm);\
else\
(header)->tail->field.next = (elm);\
(header)->tail = (elm);\
}
/*
* insert <elm> after <listelm> of list anchored at <header>
*
* header - ptr to the header field in the header element
* listelm - ptr to the list element at insertion point
* elm - ptr to the list element to be inserted
* field - name of the link field in the list element
*/
#define CDLL_INSERT_AFTER(header, listelm, elm, field) {\
(elm)->field.next = (listelm)->field.next;\
(elm)->field.prev = (listelm);\
if ((listelm)->field.next == (void *)(header))\
(header)->tail = (elm);\
else\
(listelm)->field.next->field.prev = (elm);\
(listelm)->field.next = (elm);\
}
/*
* insert <elm> before <listelm> of list anchored at <header>
*
* header - ptr to the header field in the header element
* listelm - ptr to list element at insertion point
* elm - ptr to the element to be inserted
* field - name of the link field in the list element
*/
#define CDLL_INSERT_BEFORE(header, listelm, elm, field) {\
(elm)->field.next = (listelm);\
(elm)->field.prev = (listelm)->field.prev;\
if ((listelm)->field.prev == (void *)(header))\
(header)->head = (elm);\
else\
(listelm)->field.prev->field.next = (elm);\
(listelm)->field.prev = (elm);\
}
/*
* remove <elm> from list anchored at <header>
*
* header - ptr to the header field in the header element
* elm - ptr to the list element to be removed
* field - name of the link field in the list element
*/
#define CDLL_REMOVE(header, elm, field) {\
if ((elm)->field.next == (void *)(header))\
(header)->tail = (elm)->field.prev;\
else\
(elm)->field.next->field.prev = (elm)->field.prev;\
if ((elm)->field.prev == (void *)(header))\
(header)->head = (elm)->field.next;\
else\
(elm)->field.prev->field.next = (elm)->field.next;\
}
#define CDLL_MOVE_TO_HEAD(header, elm, field) {\
if ((elm)->field.prev != (void *)(header))\
{\
if ((elm)->field.next == (void *)(header))\
(header)->tail = (elm)->field.prev;\
else\
(elm)->field.next->field.prev = (elm)->field.prev;\
(elm)->field.prev->field.next = (elm)->field.next;\
(elm)->field.next = (header)->head;\
(elm)->field.prev = (void *)(header);\
(header)->head->field.prev = (elm);\
(header)->head = (elm);\
}\
}
#define CDLL_MOVE_TO_TAIL(header, elm, field) {\
if ((elm)->field.next != (void *)(header))\
{\
(elm)->field.next->field.prev = (elm)->field.prev;\
if ((elm)->field.prev == (void *)(header))\
(header)->head = (elm)->field.next;\
else\
(elm)->field.prev->field.next = (elm)->field.next;\
(elm)->field.next = (void *)(header);\
(elm)->field.prev = (header)->tail;\
(header)->tail->field.next = (elm);\
(header)->tail = (elm);\
}\
}
/*
* orphan list element
*/
#define CDLL_SELF(elm, field)\
(elm)->field.next = (elm)->field.prev = (elm);
/*
* single head doubly-linked list
*
* A list is headed by a single head pointer.
* The elements are doubly linked so that an arbitrary element can be
* removed without a need to traverse the list.
* New elements can be added to the list at the head of the list, or
* after an existing element (NO insert at tail).
* A list may only be traversed in the forward direction.
* (note: the list is NULL terminated in next field.)
*
* +-----+ +->+-----+ +->+-----+ +->+-----+
* | NULL| | | h +--+ | n +----+ | NULL|
* +-----+ | +-----+ | +-----+ +-----+
* | | | p +--+ | p +--+
* | | +-----+ | +-----+ |
* +-----------------------+ |
* | |
* +-------------------------+
*/
#define LIST_HEADER(type)\
struct {\
struct type *head;\
}
#define LIST_ENTRY(type)\
struct {\
struct type *next;\
struct type **prev;\
}
#define LIST_INIT(header) { (header)->head = NULL; }
/*
* scan list
*
* header - ptr to the header (field in header element)
* elm - ptr to the element to be inserted
* field - name of the link field in list element
*
* struct header_container *container;
* struct header_type *header;
* struct element_type *elm;
*
* header = &container->header_field;
* for (elm = header->head; elm; elm = elm->field.next)
*/
#define LIST_INSERT_HEAD(header, elm, field) {\
if (((elm)->field.next = (header)->head) != NULL)\
(header)->head->field.prev = &(elm)->field.next;\
(header)->head = (elm);\
(elm)->field.prev = &(header)->head;\
}
#define LIST_INSERT_AFTER(listelm, elm, field) {\
if (((elm)->field.next = (listelm)->field.next) != NULL)\
(listelm)->field.next->field.prev = &(elm)->field.next;\
(listelm)->field.next = (elm);\
(elm)->field.prev = &(listelm)->field.next;\
}
#define LIST_REMOVE(elm, field) {\
if ((elm)->field.next != NULL)\
(elm)->field.next->field.prev = (elm)->field.prev;\
*(elm)->field.prev = (elm)->field.next;\
}
#define LIST_SELF(elm, field) {\
(elm)->field.next = NULL;\
(elm)->field.prev = &(elm)->field.next;\
}
#endif /* !_H_JFS_TYPES */