Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233/* * COPYRIGHT: See COPYRIGHT.TXT * PROJECT: Ext2 File System Driver for WinNT/2K/XP * FILE: Modules.h * PURPOSE: Header file: nls structures & linux kernel ... * PROGRAMMER: Matt Wu <mattwu@163.com> * HOMEPAGE: http://www.ext2fsd.com * UPDATE HISTORY: */
#ifndef _EXT2_MODULE_HEADER_#define _EXT2_MODULE_HEADER_
/* INCLUDES *************************************************************/
#include <linux/types.h>#include <linux/errno.h>#include <linux/rbtree.h>#include <linux/fs.h>#include <linux/log2.h>
#if _WIN32_WINNT <= 0x500#define _WIN2K_TARGET_ 1#endif
/* STRUCTS ******************************************************/
#ifndef offsetof# define offsetof(type, member) ((ULONG_PTR)&(((type *)0)->member))#endif
#ifndef container_of#define container_of(ptr, type, member) \ ((type *)((char *)ptr - (char *)offsetof(type, member)))#endif
//// Byte order swapping routines//
/* use the runtime routine or compiler's implementation */#if (defined(_M_IX86) && (_MSC_FULL_VER > 13009037)) || \ ((defined(_M_AMD64) || defined(_M_IA64)) && \ (_MSC_FULL_VER > 13009175))#ifdef __cplusplusextern "C" {#endif unsigned short __cdecl _byteswap_ushort(unsigned short); unsigned long __cdecl _byteswap_ulong (unsigned long); unsigned __int64 __cdecl _byteswap_uint64(unsigned __int64);#ifdef __cplusplus}#endif#pragma intrinsic(_byteswap_ushort)#pragma intrinsic(_byteswap_ulong)#pragma intrinsic(_byteswap_uint64)
#define RtlUshortByteSwap(_x) _byteswap_ushort((USHORT)(_x))#define RtlUlongByteSwap(_x) _byteswap_ulong((_x))#define RtlUlonglongByteSwap(_x) _byteswap_uint64((_x))
#else#ifndef __REACTOS__
USHORTFASTCALLRtlUshortByteSwap( IN USHORT Source);
ULONGFASTCALLRtlUlongByteSwap( IN ULONG Source);
ULONGLONGFASTCALLRtlUlonglongByteSwap( IN ULONGLONG Source);#endif //#ifndef __REACTOS__#endif
#define __swab16(x) RtlUshortByteSwap(x)#define __swab32(x) RtlUlongByteSwap(x)#define __swab64(x) RtlUlonglongByteSwap(x)
#define __constant_swab32 __swab32#define __constant_swab64 __swab64
#define __constant_htonl(x) __constant_swab32((x))#define __constant_ntohl(x) __constant_swab32((x))#define __constant_htons(x) __constant_swab16((x))#define __constant_ntohs(x) __constant_swab16((x))#define __constant_cpu_to_le64(x) ((__u64)(x))#define __constant_le64_to_cpu(x) ((__u64)(x))#define __constant_cpu_to_le32(x) ((__u32)(x))#define __constant_le32_to_cpu(x) ((__u32)(x))#define __constant_cpu_to_le16(x) ((__u16)(x))#define __constant_le16_to_cpu(x) ((__u16)(x))#define __constant_cpu_to_be64(x) __constant_swab64((x))#define __constant_be64_to_cpu(x) __constant_swab64((x))#define __constant_cpu_to_be32(x) __constant_swab32((x))#define __constant_be32_to_cpu(x) __constant_swab32((x))#define __constant_cpu_to_be16(x) __constant_swab16((x))#define __constant_be16_to_cpu(x) __constant_swab16((x))#define __cpu_to_le64(x) ((__u64)(x))#define __le64_to_cpu(x) ((__u64)(x))#define __cpu_to_le32(x) ((__u32)(x))#define __le32_to_cpu(x) ((__u32)(x))#define __cpu_to_le16(x) ((__u16)(x))#define __le16_to_cpu(x) ((__u16)(x))#define __cpu_to_be64(x) __swab64((x))#define __be64_to_cpu(x) __swab64((x))#define __cpu_to_be32(x) __swab32((x))#define __be32_to_cpu(x) __swab32((x))#define __cpu_to_be16(x) __swab16((x))#define __be16_to_cpu(x) __swab16((x))#define __cpu_to_le64p(x) (*(__u64*)(x))#define __le64_to_cpup(x) (*(__u64*)(x))#define __cpu_to_le32p(x) (*(__u32*)(x))#define __le32_to_cpup(x) (*(__u32*)(x))#define __cpu_to_le16p(x) (*(__u16*)(x))#define __le16_to_cpup(x) (*(__u16*)(x))#define __cpu_to_be64p(x) __swab64p((x))#define __be64_to_cpup(x) __swab64p((x))#define __cpu_to_be32p(x) __swab32p((x))#define __be32_to_cpup(x) __swab32p((x))#define __cpu_to_be16p(x) __swab16p((x))#define __be16_to_cpup(x) __swab16p((x))#define __cpu_to_le64s(x) ((__s64)(x))#define __le64_to_cpus(x) ((__s64)(x))#define __cpu_to_le32s(x) ((__s32)(x))#define __le32_to_cpus(x) ((__s32)(x))#define __cpu_to_le16s(x) ((__s16)(x))#define __le16_to_cpus(x) ((__s16)(x))#define __cpu_to_be64s(x) __swab64s((x))#define __be64_to_cpus(x) __swab64s((x))#define __cpu_to_be32s(x) __swab32s((x))#define __be32_to_cpus(x) __swab32s((x))#define __cpu_to_be16s(x) __swab16s((x))#define __be16_to_cpus(x) __swab16s((x))
#ifndef cpu_to_le64#define cpu_to_le64 __cpu_to_le64#define le64_to_cpu __le64_to_cpu#define cpu_to_le32 __cpu_to_le32#define le32_to_cpu __le32_to_cpu#define cpu_to_le16 __cpu_to_le16#define le16_to_cpu __le16_to_cpu#endif
#define cpu_to_be64 __cpu_to_be64#define be64_to_cpu __be64_to_cpu#define cpu_to_be32 __cpu_to_be32#define be32_to_cpu __be32_to_cpu#define cpu_to_be16 __cpu_to_be16#define be16_to_cpu __be16_to_cpu#define cpu_to_le64p __cpu_to_le64p#define le64_to_cpup __le64_to_cpup#define cpu_to_le32p __cpu_to_le32p#define le32_to_cpup __le32_to_cpup#define cpu_to_le16p __cpu_to_le16p#define le16_to_cpup __le16_to_cpup#define cpu_to_be64p __cpu_to_be64p#define be64_to_cpup __be64_to_cpup#define cpu_to_be32p __cpu_to_be32p#define be32_to_cpup __be32_to_cpup#define cpu_to_be16p __cpu_to_be16p#define be16_to_cpup __be16_to_cpup#define cpu_to_le64s __cpu_to_le64s#define le64_to_cpus __le64_to_cpus#define cpu_to_le32s __cpu_to_le32s#define le32_to_cpus __le32_to_cpus#define cpu_to_le16s __cpu_to_le16s#define le16_to_cpus __le16_to_cpus#define cpu_to_be64s __cpu_to_be64s#define be64_to_cpus __be64_to_cpus#define cpu_to_be32s __cpu_to_be32s#define be32_to_cpus __be32_to_cpus#define cpu_to_be16s __cpu_to_be16s#define be16_to_cpus __be16_to_cpus
static inline void le16_add_cpu(__le16 *var, u16 val){ *var = cpu_to_le16(le16_to_cpu(*var) + val);}
static inline void le32_add_cpu(__le32 *var, u32 val){ *var = cpu_to_le32(le32_to_cpu(*var) + val);}
static inline void le64_add_cpu(__le64 *var, u64 val){ *var = cpu_to_le64(le64_to_cpu(*var) + val);}
//// Network to host byte swap functions//
#define ntohl(x) ( ( ( ( x ) & 0x000000ff ) << 24 ) | \ ( ( ( x ) & 0x0000ff00 ) << 8 ) | \ ( ( ( x ) & 0x00ff0000 ) >> 8 ) | \ ( ( ( x ) & 0xff000000 ) >> 24 ) )
#define ntohs(x) ( ( ( ( x ) & 0xff00 ) >> 8 ) | \ ( ( ( x ) & 0x00ff ) << 8 ) )
#define htonl(x) ntohl(x)#define htons(x) ntohs(x)
//// kernel printk flags//
#define KERN_EMERG "<0>" /* system is unusable */#define KERN_ALERT "<1>" /* action must be taken immediately */#define KERN_CRIT "<2>" /* critical conditions */#define KERN_ERR "<3>" /* error conditions */#define KERN_WARNING "<4>" /* warning conditions */#define KERN_NOTICE "<5>" /* normal but significant condition */#define KERN_INFO "<6>" /* informational */#define KERN_DEBUG "<7>" /* debug-level messages */
#define printk DbgPrint
/* * error pointer */#define MAX_ERRNO 4095#define IS_ERR_VALUE(x) ((x) >= (unsigned long)-MAX_ERRNO)
static inline void *ERR_PTR(long error){ return (void *)(long_ptr_t) error;}
static inline long PTR_ERR(const void *ptr){ return (long)(long_ptr_t) ptr;}
static inline long IS_ERR(const void *ptr){ return IS_ERR_VALUE((unsigned long)(long_ptr_t)ptr);}
#define BUG_ON(c) assert(!(c))
#define WARN_ON(c) BUG_ON(c)
//// Linux module definitions//
#define likely#define unlikely
#define __init#define __exit
#define THIS_MODULE NULL#define MODULE_LICENSE(x)#define MODULE_ALIAS_NLS(x)#define EXPORT_SYMBOL(x)
#define try_module_get(x) (TRUE)#define module_put(x)
#define module_init(X) int __init module_##X() {return X();}#define module_exit(X) void __exit module_##X() {X();}
#define DECLARE_INIT(X) int __init module_##X(void)#define DECLARE_EXIT(X) void __exit module_##X(void)
#define LOAD_MODULE(X) do { \ rc = module_##X(); \ } while(0)
#define UNLOAD_MODULE(X) do { \ module_##X(); \ } while(0)
#define LOAD_NLS LOAD_MODULE#define UNLOAD_NLS UNLOAD_MODULE
//// spinlocks .....//
typedef struct _spinlock_t {
KSPIN_LOCK lock; KIRQL irql;} spinlock_t;
#define spin_lock_init(sl) KeInitializeSpinLock(&((sl)->lock))#define spin_lock(sl) KeAcquireSpinLock(&((sl)->lock), &((sl)->irql))#define spin_unlock(sl) KeReleaseSpinLock(&((sl)->lock), (sl)->irql)#define spin_lock_irqsave(sl, flags) do {spin_lock(sl); flags=(sl)->irql;} while(0)#define spin_unlock_irqrestore(sl, flags) do {ASSERT((KIRQL)(flags)==(sl)->irql); spin_unlock(sl);} while(0)
#define assert_spin_locked(x) do {} while(0)
/* * Does a critical section need to be broken due to another * task waiting?: (technically does not depend on CONFIG_PREEMPT, * but a general need for low latency) */static inline int spin_needbreak(spinlock_t *lock){#ifdef CONFIG_PREEMPT return spin_is_contended(lock);#else return 0;#endif}
//// bit operations//
/** * __set_bit - Set a bit in memory * @nr: the bit to set * @addr: the address to start counting from * * Unlike set_bit(), this function is non-atomic and may be reordered. * If it's called on the same region of memory simultaneously, the effect * may be that only one operation succeeds. */static inline int set_bit(int nr, volatile unsigned long *addr){ addr += (nr >> ORDER_PER_LONG); nr &= (BITS_PER_LONG - 1);
return !!(InterlockedOr(addr, (1 << nr)) & (1 << nr));}
/** * clear_bit - Clears a bit in memory * @nr: Bit to clear * @addr: Address to start counting from * * clear_bit() is atomic and may not be reordered. However, it does * not contain a memory barrier, so if it is used for locking purposes, * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit() * in order to ensure changes are visible on other processors. */static inline int clear_bit(int nr, volatile unsigned long *addr){ addr += (nr >> ORDER_PER_LONG); nr &= (BITS_PER_LONG - 1);
return !!(InterlockedAnd(addr, ~(1 << nr)) & (1 << nr));}
/** * test_and_clear_bit - Clear a bit and return its old value * @nr: Bit to clear * @addr: Address to count from * * This operation is atomic and cannot be reordered. * It also implies a memory barrier. */static inline int test_and_clear_bit(int nr, volatile unsigned long *addr){ return clear_bit(nr, addr);}
/* * test */static int test_bit(int nr, volatile const unsigned long *addr){ return !!((1 << (nr & (BITS_PER_LONG - 1))) & (addr[nr >> ORDER_PER_LONG]));}
/** * test_and_set_bit - Set a bit and return its old value * @nr: Bit to set * @addr: Address to count from * * This operation is atomic and cannot be reordered. * It also implies a memory barrier. */static inline int test_and_set_bit(int nr, volatile unsigned long *addr){ return set_bit(nr, addr);}
//// list definition ...//
#include <linux/list.h>
/********************************************* * linux scheduler related structures **********************************************/
//// task structure//
#define TASK_INTERRUPTIBLE 1#define TASK_UNINTERRUPTIBLE 2
struct task_struct { pid_t pid; pid_t tid; char comm[32]; void * journal_info;};
extern struct task_struct *current;
//// scheduler routines//
#ifdef __REACTOS__static inline int cond_resched() {#elsestatic inline cond_resched() {#endif return FALSE;}#ifdef __REACTOS__static inline int need_resched() {#elsestatic inline need_resched() {#endif return FALSE;}
#define yield() do {} while(0)#define might_sleep() do {} while(0)
//// mutex//
typedef struct mutex { FAST_MUTEX lock;} mutex_t;
#define mutex_init(x) ExInitializeFastMutex(&((x)->lock))#define mutex_lock(x) ExAcquireFastMutex(&((x)->lock))#define mutex_unlock(x) ExReleaseFastMutex(&((x)->lock))
//// wait_queue//
typedef PVOID wait_queue_t;
#define WQ_FLAG_EXCLUSIVE 0x01#define WQ_FLAG_AUTO_REMOVAL 0x02
struct __wait_queue { unsigned int flags; void * private; KEVENT event; struct list_head task_list;};
#define DEFINE_WAIT(name) \ wait_queue_t name = (PVOID)wait_queue_create();
/*struct wait_bit_key { void *flags; int bit_nr;};
struct wait_bit_queue { struct wait_bit_key key; wait_queue_t wait;};*/
struct __wait_queue_head { spinlock_t lock; struct list_head task_list;};typedef struct __wait_queue_head wait_queue_head_t;
#define is_sync_wait(wait) (TRUE)#define set_current_state(state) do {} while(0)#define __set_current_state(state) do {} while(0)
void init_waitqueue_head(wait_queue_head_t *q);int wake_up(wait_queue_head_t *queue);
/* * Waitqueues which are removed from the waitqueue_head at wakeup time */struct __wait_queue * wait_queue_create();void wait_queue_destroy(struct __wait_queue *);
void prepare_to_wait(wait_queue_head_t *q, wait_queue_t *wait, int state);void prepare_to_wait_exclusive(wait_queue_head_t *q, wait_queue_t *wait, int state);void finish_wait(wait_queue_head_t *q, wait_queue_t *wait);int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key);int wake_bit_function(wait_queue_t *wait, unsigned mode, int sync, void *key);
//// timer structure//
struct timer_list { struct list_head entry; unsigned long expires;
void (*function)(unsigned long); unsigned long data;
#ifdef CONFIG_TIMER_STATS void *start_site; char start_comm[16]; int start_pid;#endif};
typedef struct kmem_cache kmem_cache_t;
struct block_device {
unsigned long bd_flags; /* flags */ atomic_t bd_count; /* reference count */ PDEVICE_OBJECT bd_dev; /* device object */ ANSI_STRING bd_name; /* name in ansi string */ DISK_GEOMETRY bd_geo; /* disk geometry */ PARTITION_INFORMATION bd_part; /* partition information */ void * bd_priv; /* pointers to EXT2_VCB NULL if it's a journal dev */ PFILE_OBJECT bd_volume; /* streaming object file */ LARGE_MCB bd_extents; /* dirty extents */
kmem_cache_t * bd_bh_cache;/* memory cache for buffer_head */ ERESOURCE bd_bh_lock; /* lock for bh tree and reaper list */ struct rb_root bd_bh_root; /* buffer_head red-black tree root */ LIST_ENTRY bd_bh_free; /* reaper list */ KEVENT bd_bh_notify; /* notification event for cleanup */};
//// page information//
// vom trata paginile in felul urmator:// alocam la sfarsitul structurii inca PAGE_SIZE octeti cand alocam o structura// de tip pagina - acolo vor veni toate buffer-headurile// deci -> page_address(page) = page + sizeof(page)#define page_address(_page) ((char*)_page + sizeof(struct page))
typedef struct page { void *addr; void *mapping; void *private; atomic_t count; __u32 index; __u32 flags;} mem_map_t;
#define get_page(p) atomic_inc(&(p)->count)
#define PG_locked 0 /* Page is locked. Don't touch. */#define PG_error 1#define PG_referenced 2#define PG_uptodate 3#define PG_dirty 4#define PG_unused 5#define PG_lru 6#define PG_active 7#define PG_slab 8#define PG_skip 10#define PG_highmem 11#define PG_checked 12 /* kill me in 2.5.<early>. */#define PG_arch_1 13#define PG_reserved 14#define PG_launder 15 /* written out by VM pressure.. */#define PG_fs_1 16 /* Filesystem specific */
#ifndef arch_set_page_uptodate#define arch_set_page_uptodate(page)#endif
/* Make it prettier to test the above... */#define UnlockPage(page) unlock_page(page)#define Page_Uptodate(page) test_bit(PG_uptodate, &(page)->flags)#define SetPageUptodate(page) \ do { \ arch_set_page_uptodate(page); \ set_bit(PG_uptodate, &(page)->flags); \ } while (0)#define ClearPageUptodate(page) clear_bit(PG_uptodate, &(page)->flags)#define PageDirty(page) test_bit(PG_dirty, &(page)->flags)#define SetPageDirty(page) set_bit(PG_dirty, &(page)->flags)#define ClearPageDirty(page) clear_bit(PG_dirty, &(page)->flags)#define PageLocked(page) test_bit(PG_locked, &(page)->flags)#define LockPage(page) set_bit(PG_locked, &(page)->flags)#define TryLockPage(page) test_and_set_bit(PG_locked, &(page)->flags)#define PageChecked(page) test_bit(PG_checked, &(page)->flags)#define SetPageChecked(page) set_bit(PG_checked, &(page)->flags)#define ClearPageChecked(page) clear_bit(PG_checked, &(page)->flags)#define PageLaunder(page) test_bit(PG_launder, &(page)->flags)#define SetPageLaunder(page) set_bit(PG_launder, &(page)->flags)#define ClearPageLaunder(page) clear_bit(PG_launder, &(page)->flags)#define ClearPageArch1(page) clear_bit(PG_arch_1, &(page)->flags)
#define PageError(page) test_bit(PG_error, &(page)->flags)#define SetPageError(page) set_bit(PG_error, &(page)->flags)#define ClearPageError(page) clear_bit(PG_error, &(page)->flags)#define PageReferenced(page) test_bit(PG_referenced, &(page)->flags)#define SetPageReferenced(page) set_bit(PG_referenced, &(page)->flags)#define ClearPageReferenced(page) clear_bit(PG_referenced, &(page)->flags)
#define PageActive(page) test_bit(PG_active, &(page)->flags)#define SetPageActive(page) set_bit(PG_active, &(page)->flags)#define ClearPageActive(page) clear_bit(PG_active, &(page)->flags)
extern unsigned long __get_free_pages(unsigned int gfp_mask, unsigned int order);#define __get_free_page(gfp_mask) \ __get_free_pages((gfp_mask),0)
extern void __free_pages(struct page *page, unsigned int order);extern void free_pages(unsigned long addr, unsigned int order);
#define __free_page(page) __free_pages((page), 0)#define free_page(addr) free_pages((addr),0)
#ifndef __REACTOS__extern void truncate_inode_pages(struct address_space *, loff_t);#endif
#define __GFP_HIGHMEM 0x02
#define __GFP_WAIT 0x10 /* Can wait and reschedule? */#define __GFP_HIGH 0x20 /* Should access emergency pools? */#define __GFP_IO 0x40 /* Can start low memory physical IO? */#define __GFP_HIGHIO 0x80 /* Can start high mem physical IO? */#define __GFP_FS 0x100 /* Can call down to low-level FS? */
#define GFP_ATOMIC (__GFP_HIGH)#define GFP_USER ( __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_FS)#define GFP_HIGHUSER ( __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_FS | __GFP_HIGHMEM)#define GFP_KERNEL (__GFP_HIGH | __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_FS)#define GFP_NOFS 0#define __GFP_NOFAIL 0
#define KM_USER0 0
//// buffer head definitions//
enum bh_state_bits { BH_Uptodate, /* Contains valid data */ BH_Dirty, /* Is dirty */ BH_Verified, /* Is verified */ BH_Lock, /* Is locked */ BH_Req, /* Has been submitted for I/O */ BH_Uptodate_Lock, /* Used by the first bh in a page, to serialise * IO completion of other buffers in the page */
BH_Mapped, /* Has a disk mapping */ BH_New, /* Disk mapping was newly created by get_block */ BH_Async_Read, /* Is under end_buffer_async_read I/O */ BH_Async_Write, /* Is under end_buffer_async_write I/O */ BH_Delay, /* Buffer is not yet allocated on disk */ BH_Boundary, /* Block is followed by a discontiguity */ BH_Write_EIO, /* I/O error on write */ BH_Ordered, /* ordered write */ BH_Eopnotsupp, /* operation not supported (barrier) */ BH_Unwritten, /* Buffer is allocated on disk but not written */
BH_PrivateStart, /* not a state bit, but the first bit available * for private allocation by other entities */};
#define PAGE_CACHE_SIZE (PAGE_SIZE)#define PAGE_CACHE_SHIFT (12)#define MAX_BUF_PER_PAGE (PAGE_CACHE_SIZE / 512)
#ifdef __REACTOS__struct buffer_head;#endiftypedef void (bh_end_io_t)(struct buffer_head *bh, int uptodate);
/* * Historically, a buffer_head was used to map a single block * within a page, and of course as the unit of I/O through the * filesystem and block layers. Nowadays the basic I/O unit * is the bio, and buffer_heads are used for extracting block * mappings (via a get_block_t call), for tracking state within * a page (via a page_mapping) and for wrapping bio submission * for backward compatibility reasons (e.g. submit_bh). */struct buffer_head { LIST_ENTRY b_link; /* to be added to reaper list */ unsigned long b_state; /* buffer state bitmap (see above) */ struct page *b_page; /* the page this bh is mapped to */ PMDL b_mdl; /* MDL of the locked buffer */ void *b_bcb; /* BCB of the buffer */
// kdev_t b_dev; /* device (B_FREE = free) */ struct block_device *b_bdev; /* block device object */
blkcnt_t b_blocknr; /* start block number */ size_t b_size; /* size of mapping */ char * b_data; /* pointer to data within the page */ bh_end_io_t *b_end_io; /* I/O completion */ void *b_private; /* reserved for b_end_io */ // struct list_head b_assoc_buffers; /* associated with another mapping */ // struct address_space *b_assoc_map; /* mapping this buffer is associated with */ atomic_t b_count; /* users using this buffer_head */ struct rb_node b_rb_node; /* Red-black tree node entry */
LARGE_INTEGER b_ts_creat; /* creation time*/ LARGE_INTEGER b_ts_drop; /* drop time (to be released) */};
/* * macro tricks to expand the set_buffer_foo(), clear_buffer_foo() * and buffer_foo() functions. */#define BUFFER_FNS(bit, name) \static inline void set_buffer_##name(struct buffer_head *bh) \{ \ set_bit(BH_##bit, &(bh)->b_state); \} \static inline void clear_buffer_##name(struct buffer_head *bh) \{ \ clear_bit(BH_##bit, &(bh)->b_state); \} \static inline int buffer_##name(const struct buffer_head *bh) \{ \ return test_bit(BH_##bit, &(bh)->b_state); \}
/* * test_set_buffer_foo() and test_clear_buffer_foo() */#define TAS_BUFFER_FNS(bit, name) \static inline int test_set_buffer_##name(struct buffer_head *bh) \{ \ return test_and_set_bit(BH_##bit, &(bh)->b_state); \} \static inline int test_clear_buffer_##name(struct buffer_head *bh) \{ \ return test_and_clear_bit(BH_##bit, &(bh)->b_state); \} \
/* * Emit the buffer bitops functions. Note that there are also functions * of the form "mark_buffer_foo()". These are higher-level functions which * do something in addition to setting a b_state bit. */BUFFER_FNS(Uptodate, uptodate)BUFFER_FNS(Dirty, dirty)TAS_BUFFER_FNS(Dirty, dirty)BUFFER_FNS(Verified, verified)BUFFER_FNS(Lock, locked)TAS_BUFFER_FNS(Lock, locked)BUFFER_FNS(Req, req)TAS_BUFFER_FNS(Req, req)BUFFER_FNS(Mapped, mapped)BUFFER_FNS(New, new)BUFFER_FNS(Async_Read, async_read)BUFFER_FNS(Async_Write, async_write)BUFFER_FNS(Delay, delay)BUFFER_FNS(Boundary, boundary)BUFFER_FNS(Write_EIO, write_io_error)BUFFER_FNS(Ordered, ordered)BUFFER_FNS(Eopnotsupp, eopnotsupp)BUFFER_FNS(Unwritten, unwritten)
#define bh_offset(bh) ((unsigned long)(bh)->b_data & ~PAGE_MASK)#define touch_buffer(bh) mark_page_accessed(bh->b_page)
/* If we *know* page->private refers to buffer_heads */
#define page_buffers(page) \ ( \ BUG_ON(!PagePrivate(page)), \ ((struct buffer_head *)page_private(page)) \ )#define page_has_buffers(page) PagePrivate(page)
/* * Declarations */
void mark_buffer_dirty(struct buffer_head *bh);void init_buffer(struct buffer_head *, bh_end_io_t *, void *);void set_bh_page(struct buffer_head *bh, struct page *page, unsigned long offset);int try_to_free_buffers(struct page *);struct buffer_head *alloc_page_buffers(struct page *page, unsigned long size, int retry);void create_empty_buffers(struct page *, unsigned long, unsigned long b_state);
/* Things to do with buffers at mapping->private_list */void mark_buffer_dirty_inode(struct buffer_head *bh, struct inode *inode);int inode_has_buffers(struct inode *);void invalidate_inode_buffers(struct inode *);int remove_inode_buffers(struct inode *inode);#ifndef __REACTOS__int sync_mapping_buffers(struct address_space *mapping);#endifvoid unmap_underlying_metadata(struct block_device *bdev, sector_t block);
void mark_buffer_async_write(struct buffer_head *bh);void invalidate_bdev(struct block_device *);int sync_blockdev(struct block_device *bdev);void __wait_on_buffer(struct buffer_head *);wait_queue_head_t *bh_waitq_head(struct buffer_head *bh);int fsync_bdev(struct block_device *);struct super_block *freeze_bdev(struct block_device *);void thaw_bdev(struct block_device *, struct super_block *);int fsync_super(struct super_block *);int fsync_no_super(struct block_device *);struct buffer_head *__find_get_block(struct block_device *bdev, sector_t block, unsigned long size);struct buffer_head *get_block_bh(struct block_device *bdev, sector_t block, unsigned long size, int zero);struct buffer_head *__getblk(struct block_device *bdev, sector_t block, unsigned long size);void __brelse(struct buffer_head *);void __bforget(struct buffer_head *);void __breadahead(struct block_device *, sector_t block, unsigned int size);struct buffer_head *__bread(struct block_device *, sector_t block, unsigned size);void invalidate_bh_lrus(void);struct buffer_head *alloc_buffer_head(gfp_t gfp_flags);void free_buffer_head(struct buffer_head * bh);void unlock_buffer(struct buffer_head *bh);void __lock_buffer(struct buffer_head *bh);void ll_rw_block(int, int, struct buffer_head * bh[]);int sync_dirty_buffer(struct buffer_head *bh);int submit_bh(int, struct buffer_head *);void write_boundary_block(struct block_device *bdev, sector_t bblock, unsigned blocksize);int bh_uptodate_or_lock(struct buffer_head *bh);int bh_submit_read(struct buffer_head *bh);/* They are separately managed */struct buffer_head *extents_bread(struct super_block *sb, sector_t block);struct buffer_head *extents_bwrite(struct super_block *sb, sector_t block);void extents_mark_buffer_dirty(struct buffer_head *bh);void extents_brelse(struct buffer_head *bh);void extents_bforget(struct buffer_head *bh);void buffer_head_remove(struct block_device *bdev, struct buffer_head *bh);
extern int buffer_heads_over_limit;
/* * Generic address_space_operations implementations for buffer_head-backed * address_spaces. */
#if 0
int block_write_full_page(struct page *page, get_block_t *get_block, struct writeback_control *wbc);int block_read_full_page(struct page*, get_block_t*);int block_write_begin(struct file *, struct address_space *, loff_t, unsigned, unsigned, struct page **, void **, get_block_t*);int block_write_end(struct file *, struct address_space *, loff_t, unsigned, unsigned, struct page *, void *);int generic_write_end(struct file *, struct address_space *, loff_t, unsigned, unsigned, struct page *, void *);
int block_prepare_write(struct page*, unsigned, unsigned, get_block_t*);int cont_write_begin(struct file *, struct address_space *, loff_t, unsigned, unsigned, struct page **, void **, get_block_t *, loff_t *);int block_page_mkwrite(struct vm_area_struct *vma, struct page *page, get_block_t get_block);sector_t generic_block_bmap(struct address_space *, sector_t, get_block_t *);int generic_commit_write(struct file *, struct page *, unsigned, unsigned);int block_truncate_page(struct address_space *, loff_t, get_block_t *);int file_fsync(struct file *, struct dentry *, int);int nobh_write_begin(struct file *, struct address_space *, loff_t, unsigned, unsigned, struct page **, void **, get_block_t*);int nobh_write_end(struct file *, struct address_space *, loff_t, unsigned, unsigned, struct page *, void *);int nobh_truncate_page(struct address_space *, loff_t, get_block_t *);int nobh_writepage(struct page *page, get_block_t *get_block, struct writeback_control *wbc);int generic_cont_expand_simple(struct inode *inode, loff_t size);#endif
void block_invalidatepage(struct page *page, unsigned long offset);void page_zero_new_buffers(struct page *page, unsigned from, unsigned to);int block_commit_write(struct page *page, unsigned from, unsigned to);void block_sync_page(struct page *);
void buffer_init(void);
/* * inline definitions */#if 0static inline void attach_page_buffers(struct page *page, struct buffer_head *head){ page_cache_get(page); SetPagePrivate(page); set_page_private(page, (unsigned long)head);}#endif
static inline void get_bh(struct buffer_head *bh){ atomic_inc(&bh->b_count);}
static inline void put_bh(struct buffer_head *bh){ if (bh) __brelse(bh);}
static inline void brelse(struct buffer_head *bh){ if (bh) __brelse(bh);}
static inline void fini_bh(struct buffer_head **bh){ if (bh && *bh) { brelse(*bh); *bh = NULL; }}
static inline void bforget(struct buffer_head *bh){ if (bh) __bforget(bh);}
static inline struct buffer_head * sb_getblk(struct super_block *sb, sector_t block){ return get_block_bh(sb->s_bdev, block, sb->s_blocksize, 0);}
static inline struct buffer_head * sb_getblk_zero(struct super_block *sb, sector_t block){ return get_block_bh(sb->s_bdev, block, sb->s_blocksize, 1);}
static inline struct buffer_head * sb_bread(struct super_block *sb, sector_t block){ struct buffer_head *bh = __getblk(sb->s_bdev, block, sb->s_blocksize); if (!bh) return NULL; if (!buffer_uptodate(bh) && (bh_submit_read(bh) < 0)) { brelse(bh); return NULL; } return bh;}
static inline struct buffer_head * sb_find_get_block(struct super_block *sb, sector_t block){ return __find_get_block(sb->s_bdev, block, sb->s_blocksize);}
static inline voidmap_bh(struct buffer_head *bh, struct super_block *sb, sector_t block){ set_buffer_mapped(bh); bh->b_bdev = sb->s_bdev; bh->b_blocknr = block; bh->b_size = sb->s_blocksize;}
/* * Calling wait_on_buffer() for a zero-ref buffer is illegal, so we call into * __wait_on_buffer() just to trip a debug check. Because debug code in inline * functions is bloaty. */
static inline void wait_on_buffer(struct buffer_head *bh){ might_sleep(); if (buffer_locked(bh) || atomic_read(&bh->b_count) == 0) __wait_on_buffer(bh);}
static inline void lock_buffer(struct buffer_head *bh){ might_sleep(); if (test_set_buffer_locked(bh)) __lock_buffer(bh);}
extern int __set_page_dirty_buffers(struct page *page);
//// unicode character//
struct nls_table { char *charset; char *alias; int (*uni2char) (wchar_t uni, unsigned char *out, int boundlen); int (*char2uni) (const unsigned char *rawstring, int boundlen, wchar_t *uni); unsigned char *charset2lower; unsigned char *charset2upper; struct module *owner; struct nls_table *next;};
/* this value hold the maximum octet of charset */#define NLS_MAX_CHARSET_SIZE 6 /* for UTF-8 */
/* nls.c */extern int register_nls(struct nls_table *);extern int unregister_nls(struct nls_table *);extern struct nls_table *load_nls(char *);extern void unload_nls(struct nls_table *);extern struct nls_table *load_nls_default(void);
extern int utf8_mbtowc(wchar_t *, const __u8 *, int);extern int utf8_mbstowcs(wchar_t *, const __u8 *, int);extern int utf8_wctomb(__u8 *, wchar_t, int);extern int utf8_wcstombs(__u8 *, const wchar_t *, int);
//// kernel jiffies//
#define HZ (100)
static inline __u32 JIFFIES(){ LARGE_INTEGER Tick;
KeQueryTickCount(&Tick); Tick.QuadPart *= KeQueryTimeIncrement(); Tick.QuadPart /= (10000000 / HZ);
return Tick.LowPart;}
#define jiffies JIFFIES()
//// memory routines//
#ifdef _WIN2K_TARGET_
typedef GUID UUID;NTKERNELAPINTSTATUSExUuidCreate( OUT UUID *Uuid);
NTKERNELAPIPVOIDNTAPIExAllocatePoolWithTag( IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes, IN ULONG Tag);
#define ExFreePoolWithTag(_P, _T) ExFreePool(_P)#endif
PVOID Ext2AllocatePool( IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes, IN ULONG Tag);
VOIDExt2FreePool( IN PVOID P, IN ULONG Tag);
void *kzalloc(int size, int flags);#define kmalloc(size, gfp) Ext2AllocatePool(NonPagedPool, size, 'JBDM')#define kfree(p) Ext2FreePool(p, 'JBDM')
/* memory slab */
#define SLAB_HWCACHE_ALIGN 0x00002000U /* align objs on a h/w cache lines */#define SLAB_KERNEL 0x00000001U#define SLAB_TEMPORARY 0x00000002U
typedef void (*kmem_cache_cb_t)(void*, kmem_cache_t *, unsigned long);
struct kmem_cache { CHAR name[32]; ULONG flags; ULONG size; atomic_t count; atomic_t acount; NPAGED_LOOKASIDE_LIST la; kmem_cache_cb_t constructor;};
kmem_cache_t *kmem_cache_create( const char *name, size_t size, size_t offset, unsigned long flags, kmem_cache_cb_t ctor);
void* kmem_cache_alloc(kmem_cache_t *kc, int flags);void kmem_cache_free(kmem_cache_t *kc, void *p);int kmem_cache_destroy(kmem_cache_t *kc);
//// block device//
#define BDEVNAME_SIZE 32 /* Largest string for a blockdev identifier */
//// ll_rw_block ....//
#define RW_MASK 1#define RWA_MASK 2#define READ 0#define WRITE 1#define READA 2 /* read-ahead - don't block if no resources */#define SWRITE 3 /* for ll_rw_block() - wait for buffer lock */#define READ_SYNC (READ | (1 << BIO_RW_SYNC))#define READ_META (READ | (1 << BIO_RW_META))#define WRITE_SYNC (WRITE | (1 << BIO_RW_SYNC))#define WRITE_BARRIER ((1 << BIO_RW) | (1 << BIO_RW_BARRIER))
//// timer routines//
/* * These inlines deal with timer wrapping correctly. You are * strongly encouraged to use them * 1. Because people otherwise forget * 2. Because if the timer wrap changes in future you won't have to * alter your driver code. * * time_after(a,b) returns true if the time a is after time b. * * Do this with "<0" and ">=0" to only test the sign of the result. A * good compiler would generate better code (and a really good compiler * wouldn't care). Gcc is currently neither. */#define typecheck(x, y) (TRUE)
#define time_after(a,b) \ (typecheck(unsigned long, a) && \ typecheck(unsigned long, b) && \ ((long)(b) - (long)(a) < 0))#define time_before(a,b) time_after(b,a)
#define time_after_eq(a,b) \ (typecheck(unsigned long, a) && \ typecheck(unsigned long, b) && \ ((long)(a) - (long)(b) >= 0))#define time_before_eq(a,b) time_after_eq(b,a)
#define time_in_range(a,b,c) \ (time_after_eq(a,b) && \ time_before_eq(a,c))
#define smp_rmb() do {}while(0)
static inline __u32 do_div64 (__u64 * n, __u64 b){ __u64 mod;
mod = *n % b; *n = *n / b; return (__u32) mod;}#define do_div(n, b) do_div64(&(n), (__u64)b)
#endif // _EXT2_MODULE_HEADER_