[EXT2_NEW] Add Matt Wu's ext2 filesystem driver. Not enabled by default just yet...
authorAmine Khaldi <amine.khaldi@reactos.org>
Mon, 12 Oct 2015 10:19:10 +0000 (10:19 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Mon, 12 Oct 2015 10:19:10 +0000 (10:19 +0000)
svn path=/trunk/; revision=69509

108 files changed:
reactos/drivers/filesystems/CMakeLists.txt
reactos/drivers/filesystems/ext2_new/CMakeLists.txt [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/ext2fs.rc [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/inc/common.h [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/inc/ext2fs.h [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/inc/linux/Ext2_fs.h [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/inc/linux/atomic.h [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/inc/linux/bit_spinlock.h [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/inc/linux/bitops.h [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/inc/linux/config.h [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/inc/linux/errno.h [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/inc/linux/ext3_fs.h [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/inc/linux/ext3_fs_i.h [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/inc/linux/ext3_fs_sb.h [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/inc/linux/ext3_jbd.h [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/inc/linux/ext4.h [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/inc/linux/ext4_ext.h [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/inc/linux/ext4_jbd2.h [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/inc/linux/fs.h [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/inc/linux/group.h [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/inc/linux/jbd.h [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/inc/linux/journal-head.h [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/inc/linux/list.h [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/inc/linux/log2.h [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/inc/linux/module.h [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/inc/linux/rbtree.h [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/inc/linux/stddef.h [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/inc/linux/types.h [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/inc/resource.h [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/block.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/cleanup.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/close.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/cmcb.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/create.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/debug.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/devctl.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/dirctl.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/dispatch.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/except.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/ext2.rc [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/ext3/generic.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/ext3/htree.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/ext3/indirect.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/ext3/recover.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/ext4/ext4_bh.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/ext4/ext4_extents.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/ext4/ext4_jbd2.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/ext4/extents.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/fastio.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/fileinfo.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/flush.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/fsctl.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/init.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/jbd/recovery.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/jbd/replay.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/jbd/revoke.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/linux.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/lock.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/memory.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/misc.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/nls.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/nls/nls_ascii.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/nls/nls_base.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/nls/nls_cp1250.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/nls/nls_cp1251.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/nls/nls_cp1255.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/nls/nls_cp437.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/nls/nls_cp737.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/nls/nls_cp775.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/nls/nls_cp850.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/nls/nls_cp852.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/nls/nls_cp855.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/nls/nls_cp857.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/nls/nls_cp860.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/nls/nls_cp861.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/nls/nls_cp862.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/nls/nls_cp863.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/nls/nls_cp864.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/nls/nls_cp865.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/nls/nls_cp866.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/nls/nls_cp869.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/nls/nls_cp874.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/nls/nls_cp932.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/nls/nls_cp936.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/nls/nls_cp949.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/nls/nls_cp950.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/nls/nls_euc-jp.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/nls/nls_iso8859-1.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/nls/nls_iso8859-13.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/nls/nls_iso8859-14.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/nls/nls_iso8859-15.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/nls/nls_iso8859-2.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/nls/nls_iso8859-3.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/nls/nls_iso8859-4.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/nls/nls_iso8859-5.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/nls/nls_iso8859-6.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/nls/nls_iso8859-7.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/nls/nls_iso8859-9.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/nls/nls_koi8-r.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/nls/nls_koi8-ru.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/nls/nls_koi8-u.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/nls/nls_utf8.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/pnp.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/rbtree.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/read.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/shutdown.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/volinfo.c [new file with mode: 0644]
reactos/drivers/filesystems/ext2_new/src/write.c [new file with mode: 0644]

index 20a81ae..1df81cc 100644 (file)
@@ -1,6 +1,7 @@
 
 add_subdirectory(cdfs)
 add_subdirectory(ext2)
+#add_subdirectory(ext2_new)
 add_subdirectory(fastfat)
 #add_subdirectory(fastfat_new)
 add_subdirectory(fs_rec)
diff --git a/reactos/drivers/filesystems/ext2_new/CMakeLists.txt b/reactos/drivers/filesystems/ext2_new/CMakeLists.txt
new file mode 100644 (file)
index 0000000..f02de3c
--- /dev/null
@@ -0,0 +1,105 @@
+
+include_directories(${REACTOS_SOURCE_DIR}/include/reactos/drivers
+                    inc)
+
+list(APPEND SOURCE
+    src/init.c
+    src/ext3/generic.c
+    src/ext3/htree.c
+    src/ext3/indirect.c
+    src/ext3/recover.c
+    src/ext4/ext4_bh.c
+    src/ext4/ext4_extents.c
+    src/ext4/ext4_jbd2.c
+    src/ext4/extents.c
+    src/jbd/recovery.c
+    src/jbd/replay.c
+    src/jbd/revoke.c
+    src/nls/nls_ascii.c
+    src/nls/nls_base.c
+    src/nls/nls_cp437.c
+    src/nls/nls_cp737.c
+    src/nls/nls_cp775.c
+    src/nls/nls_cp850.c
+    src/nls/nls_cp852.c
+    src/nls/nls_cp855.c
+    src/nls/nls_cp857.c
+    src/nls/nls_cp860.c
+    src/nls/nls_cp861.c
+    src/nls/nls_cp862.c
+    src/nls/nls_cp863.c
+    src/nls/nls_cp864.c
+    src/nls/nls_cp865.c
+    src/nls/nls_cp866.c
+    src/nls/nls_cp869.c
+    src/nls/nls_cp874.c
+    src/nls/nls_cp932.c
+    src/nls/nls_cp936.c
+    src/nls/nls_cp949.c
+    src/nls/nls_cp950.c
+    src/nls/nls_cp1250.c
+    src/nls/nls_cp1251.c
+    src/nls/nls_cp1255.c
+    src/nls/nls_euc-jp.c
+    src/nls/nls_iso8859-1.c
+    src/nls/nls_iso8859-2.c
+    src/nls/nls_iso8859-3.c
+    src/nls/nls_iso8859-4.c
+    src/nls/nls_iso8859-5.c
+    src/nls/nls_iso8859-6.c
+    src/nls/nls_iso8859-7.c
+    src/nls/nls_iso8859-9.c
+    src/nls/nls_iso8859-13.c
+    src/nls/nls_iso8859-14.c
+    src/nls/nls_iso8859-15.c
+    src/nls/nls_koi8-r.c
+    src/nls/nls_koi8-ru.c
+    src/nls/nls_koi8-u.c
+    src/nls/nls_utf8.c
+    src/block.c
+    src/cleanup.c
+    src/close.c
+    src/cmcb.c
+    src/create.c
+    src/debug.c
+    src/devctl.c
+    src/dirctl.c
+    src/dispatch.c
+    src/except.c
+    src/fastio.c
+    src/fileinfo.c
+    src/flush.c
+    src/fsctl.c
+    src/linux.c
+    src/lock.c
+    src/memory.c
+    src/misc.c
+    src/nls.c
+    src/pnp.c
+    src/rbtree.c
+    src/read.c
+    src/shutdown.c
+    src/volinfo.c
+    src/write.c
+    inc/ext2fs.h)
+
+add_library(ext2fs SHARED ${SOURCE} ext2fs.rc)
+
+if(NOT MSVC)
+    add_target_compile_flags(ext2fs "-Wno-pointer-sign -Wno-unused-function")
+    if(NOT CMAKE_C_COMPILER_ID STREQUAL "Clang")
+        replace_compile_flags("-Werror" " ")
+        add_target_compile_flags(ext2fs "-Wno-unused-but-set-variable -Wno-unused-variable -Wno-missing-braces")
+    endif()
+else()
+    #disable warnings: "unreferenced local variable", "initialized, but not used variable", "benign include"
+    replace_compile_flags("/we\"4189\"" " ")
+    add_target_compile_flags(ext2fs "/wd\"4189\" /wd\"4142\" /wd\"4101\"")
+endif()
+
+target_link_libraries(ext2fs memcmp ${PSEH_LIB})
+add_definitions(-D__KERNEL__ -D_X86_)
+set_module_type(ext2fs kernelmodedriver)
+add_importlibs(ext2fs ntoskrnl hal)
+add_pch(ext2fs inc/ext2fs.h SOURCE)
+add_cd_file(TARGET ext2fs DESTINATION reactos/system32/drivers NO_CAB FOR all)
diff --git a/reactos/drivers/filesystems/ext2_new/ext2fs.rc b/reactos/drivers/filesystems/ext2_new/ext2fs.rc
new file mode 100644 (file)
index 0000000..5988979
--- /dev/null
@@ -0,0 +1,5 @@
+#define REACTOS_VERSION_DLL
+#define REACTOS_STR_FILE_DESCRIPTION  "Linux ext2 IFS Driver"
+#define REACTOS_STR_INTERNAL_NAME     "ext2fs"
+#define REACTOS_STR_ORIGINAL_FILENAME "ext2fs.sys"
+#include <reactos/version.rc>
diff --git a/reactos/drivers/filesystems/ext2_new/inc/common.h b/reactos/drivers/filesystems/ext2_new/inc/common.h
new file mode 100644 (file)
index 0000000..66ed586
--- /dev/null
@@ -0,0 +1,251 @@
+#ifndef _EXT2_COMMON_INCLUDE_
+#define _EXT2_COMMON_INCLUDE_
+
+/* global ioctl */
+#define IOCTL_APP_VOLUME_PROPERTY \
+CTL_CODE(FILE_DEVICE_UNKNOWN, 2000, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define IOCTL_APP_QUERY_PERFSTAT \
+CTL_CODE(FILE_DEVICE_UNKNOWN, 2001, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define IOCTL_APP_MOUNT_POINT \
+CTL_CODE(FILE_DEVICE_UNKNOWN, 2002, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+
+/* performance / memory allocaiton statistics */
+#define PS_IRP_CONTEXT  0x00
+#define PS_VCB          0x01
+#define PS_FCB          0x02
+#define PS_CCB          0x03
+#define PS_MCB          0x04
+#define PS_EXTENT       0x05
+#define PS_RW_CONTEXT   0x06
+#define PS_VPB          0x07
+#define PS_FILE_NAME    0x08
+#define PS_MCB_NAME     0x09
+#define PS_INODE_NAME   0x0A
+#define PS_DIR_ENTRY    0x0B
+#define PS_DIR_PATTERN  0x0C
+#define PS_DISK_EVENT   0x0D
+#define PS_DISK_BUFFER  0x0E
+#define PS_BLOCK_DATA   0x0F
+
+#define PS_EXT2_INODE   0x10
+#define PS_DENTRY       0x11
+#define PS_BUFF_HEAD    0x12
+
+#define PS_MAX_TYPE_V1  (0x10)
+#define PS_MAX_TYPE_V2  (0x30)
+
+typedef union {
+
+    ULONG           Slot[PS_MAX_TYPE_V1];
+
+    struct {
+        ULONG       IrpContext;
+        ULONG       Vcb;
+        ULONG       Fcb;
+        ULONG       Ccb;
+        ULONG       Mcb;
+        ULONG       Extent;
+        ULONG       RwContext;   /* rw context */
+        ULONG       Vpb;
+        ULONG       FileName;
+        ULONG       McbName;
+        ULONG       InodeName;
+        ULONG       DirEntry;    /* pDir */
+        ULONG       DirPattern;  /* Ccb-> in Ext2QeuryDir */
+        ULONG       ReadDiskEvent;
+        ULONG       ReadDiskBuffer;
+        ULONG       BlockData;   /* Ext2Expand&TruncateFile*/
+    };
+
+} EXT2_STAT_ARRAY_V1;
+
+typedef union {
+
+    ULONG           Slot[PS_MAX_TYPE_V2];
+
+    struct {
+        ULONG       IrpContext;
+        ULONG       Vcb;
+        ULONG       Fcb;
+        ULONG       Ccb;
+        ULONG       Mcb;
+        ULONG       Extent;
+        ULONG       RwContext;  /* rw context */
+        ULONG       Vpb;
+        ULONG       FileName;
+        ULONG       McbName;
+        ULONG       InodeName;
+        ULONG       DirEntry;   /* pDir */
+        ULONG       DirPattern; /* Ccb-> in Ext2QeuryDir */
+        ULONG       ReadDiskEvent;
+        ULONG       ReadDiskBuffer;
+        ULONG       BlockData;  /* Ext2Expand&TruncateFile*/
+        ULONG       Inodes;     /* inodes */
+        ULONG       NameEntries;    /* name dentry */
+        ULONG       BufferHead; /* Buffer Header allocations */
+    };
+
+} EXT2_STAT_ARRAY_V2;
+
+typedef struct _EXT2_PERF_STATISTICS_V1 {
+
+    /* totoal number of processed/being processed requests */
+    struct {
+        ULONG           Processed;
+        ULONG           Current;
+    } Irps [IRP_MJ_MAXIMUM_FUNCTION + 1];
+
+    /* structure size */
+    EXT2_STAT_ARRAY_V1  Unit;
+
+    /* current memory allocation statistics */
+    EXT2_STAT_ARRAY_V1  Current;
+
+    /* memory allocated in bytes */
+    EXT2_STAT_ARRAY_V1  Size;
+
+    /* totoal memory allocation statistics */
+    EXT2_STAT_ARRAY_V1  Total;
+
+} EXT2_PERF_STATISTICS_V1, *PEXT2_PERF_STATISTICS_V1;
+
+#define EXT2_PERF_STAT_MAGIC '2SPE'
+#define EXT2_PERF_STAT_VER2   2
+
+typedef struct _EXT2_PERF_STATISTICS_V2 {
+
+    ULONG               Magic;      /* EPS2 */
+    USHORT              Version;    /* 02 */
+    USHORT              Length;     /* sizeof(EXT2_PERF_STATISTICS_V2) */
+
+    /* totoal number of processed/being processed requests */
+    struct {
+        ULONG           Processed;
+        ULONG           Current;
+    } Irps [IRP_MJ_MAXIMUM_FUNCTION + 1];
+
+    /* structure size */
+    EXT2_STAT_ARRAY_V2  Unit;
+
+    /* current memory allocation statistics */
+    EXT2_STAT_ARRAY_V2  Current;
+
+    /* memory allocated in bytes */
+    EXT2_STAT_ARRAY_V2  Size;
+
+    /* totoal memory allocation statistics */
+    EXT2_STAT_ARRAY_V2  Total;
+
+} EXT2_PERF_STATISTICS_V2, *PEXT2_PERF_STATISTICS_V2;
+
+/* volume property ... */
+
+#define EXT2_VOLUME_PROPERTY_MAGIC 'EVPM'
+
+#define EXT2_FLAG_VP_SET_GLOBAL   0x00000001
+
+#define APP_CMD_QUERY_VERSION     0x00000000 /* with global flag set */
+#define APP_CMD_QUERY_CODEPAGES   0x00000001
+#define APP_CMD_QUERY_PROPERTY    0x00000002
+#define APP_CMD_SET_PROPERTY      0x00000003
+#define APP_CMD_QUERY_PROPERTY2   0x00000004
+#define APP_CMD_SET_PROPERTY2     0x00000005
+#define APP_CMD_QUERY_PROPERTY3   0x00000006
+#define APP_CMD_SET_PROPERTY3     0x00000007
+
+#define CODEPAGE_MAXLEN     0x20
+#define HIDINGPAT_LEN       0x20
+
+typedef struct _EXT2_VOLUME_PROPERTY {
+    ULONG               Magic;
+    ULONG               Flags;
+    ULONG               Command;
+    BOOLEAN             bReadonly;
+    BOOLEAN             bExt3Writable;
+    BOOLEAN             bExt2;
+    BOOLEAN             bExt3;
+    UCHAR               Codepage[CODEPAGE_MAXLEN];
+} EXT2_VOLUME_PROPERTY;
+
+#ifdef __cplusplus
+typedef struct _EXT2_VOLUME_PROPERTY2:EXT2_VOLUME_PROPERTY {
+#else   // __cplusplus
+typedef struct _EXT2_VOLUME_PROPERTY2 {
+    EXT2_VOLUME_PROPERTY ;
+#endif  // __cplusplus
+
+    /* new volume properties added after version 0.35 */
+
+    /* volume uuid */
+    __u8                           UUID[16];
+
+    /* mount point: driver letter only */
+    UCHAR                       DrvLetter;
+
+    /* checking bitmap */
+    BOOLEAN                     bCheckBitmap;
+
+    /* global hiding patterns */
+    BOOLEAN                     bHidingPrefix;
+    BOOLEAN                     bHidingSuffix;
+    CHAR                        sHidingPrefix[HIDINGPAT_LEN];
+    CHAR                        sHidingSuffix[HIDINGPAT_LEN];
+
+} EXT2_VOLUME_PROPERTY2, *PEXT2_VOLUME_PROPERTY2;
+
+#define EXT2_VPROP3_AUTOMOUNT 0x0000000000000001
+
+typedef struct _EXT2_VOLUME_PROPERTY3 {
+    EXT2_VOLUME_PROPERTY2  Prop2;
+    unsigned __int64       Flags;
+    int                    AutoMount:1;
+    int                    Reserved1:31;
+    int                    Reserved2[31];
+} EXT2_VOLUME_PROPERTY3, *PEXT2_VOLUME_PROPERTY3;
+
+/* Ext2Fsd driver version and built time */
+typedef struct _EXT2_VOLUME_PROPERTY_VERSION {
+    ULONG               Magic;
+    ULONG               Flags;
+    ULONG               Command;
+    CHAR                Version[0x1C];
+    CHAR                Time[0x20];
+    CHAR                Date[0x20];
+} EXT2_VOLUME_PROPERTY_VERSION, *PEXT2_VOLUME_PROPERTY_VERSION;
+
+/* performance statistics */
+#define EXT2_QUERY_PERFSTAT_MAGIC 'EVPM'
+#define EXT2_QUERY_PERFSTAT_VER2  0x8000000
+
+typedef struct _EXT2_QUERY_PERFSTAT {
+    ULONG                   Magic;
+    ULONG                   Flags;
+    ULONG                   Command;
+    union {
+        EXT2_PERF_STATISTICS_V1 PerfStatV1;
+        EXT2_PERF_STATISTICS_V2 PerfStatV2;
+    };
+} EXT2_QUERY_PERFSTAT, *PEXT2_QUERY_PERFSTAT;
+
+#define EXT2_QUERY_PERFSTAT_SZV1 (FIELD_OFFSET(EXT2_QUERY_PERFSTAT, PerfStatV1) + sizeof(EXT2_PERF_STATISTICS_V1))
+#define EXT2_QUERY_PERFSTAT_SZV2 (FIELD_OFFSET(EXT2_QUERY_PERFSTAT, PerfStatV1) + sizeof(EXT2_PERF_STATISTICS_V2))
+
+/* mountpoint management  */
+#define EXT2_APP_MOUNTPOINT_MAGIC 'EAMM'
+typedef struct _EXT2_MOUNT_POINT {
+    ULONG                   Magic;
+    ULONG                   Flags;
+    ULONG                   Size;
+    ULONG                   Command;
+    USHORT                  Link[256];
+    USHORT                  Name[256];
+} EXT2_MOUNT_POINT, *PEXT2_MOUNT_POINT;
+
+#define APP_CMD_ADD_DOS_SYMLINK    0x00000001
+#define APP_CMD_DEL_DOS_SYMLINK    0x00000002
+
+
+#endif /* _EXT2_COMMON_INCLUDE_ */
diff --git a/reactos/drivers/filesystems/ext2_new/inc/ext2fs.h b/reactos/drivers/filesystems/ext2_new/inc/ext2fs.h
new file mode 100644 (file)
index 0000000..3bfb60d
--- /dev/null
@@ -0,0 +1,2875 @@
+/*
+ * COPYRIGHT:        See COPYRIGHT.TXT
+ * PROJECT:          Ext2 File System Driver for WinNT/2K/XP
+ * FILE:             Ext2fs.h
+ * PURPOSE:          Header file: ext2 structures
+ * PROGRAMMER:       Matt Wu <mattwu@163.com>
+ * HOMEPAGE:         http://ext2.yeah.net
+ * UPDATE HISTORY:
+ */
+
+#ifndef _EXT2_HEADER_
+#define _EXT2_HEADER_
+
+/* INCLUDES *************************************************************/
+#include <linux/module.h>
+#include <ntdddisk.h>
+#ifdef __REACTOS__
+#include <ndk/rtlfuncs.h>
+#include <pseh/pseh2.h>
+#endif
+#include "stdio.h"
+#include <string.h>
+#include <linux/ext2_fs.h>
+#include <linux/ext3_fs.h>
+#include <linux/ext3_fs_i.h>
+#include <linux/ext4.h>
+
+/* DEBUG ****************************************************************/
+#if DBG
+# define EXT2_DEBUG   1
+#else
+# define EXT2_DEBUG   0
+#endif
+
+#define EXT_DEBUG_BREAKPOINT FALSE
+
+#if EXT2_DEBUG && EXT_DEBUG_BREAKPOINT
+//#if _X86_
+//#define DbgBreak()      __asm int 3
+//#else
+#define DbgBreak()      KdBreakPoint()
+//#endif
+#else
+#define DbgBreak()
+#endif
+
+/* STRUCTS & CONSTS******************************************************/
+
+#define EXT2FSD_VERSION                 "0.62"
+
+
+//
+// Ext2Fsd build options
+//
+
+// To support driver dynamics unload
+
+#define EXT2_UNLOAD                     FALSE
+
+// To support inode size expansion (fallocate)
+
+#define EXT2_PRE_ALLOCATION_SUPPORT     TRUE
+
+//
+// Constants
+//
+
+#define EXT2_MAX_NESTED_LINKS           (8)
+#define EXT2_LINKLEN_IN_INODE           (60)
+#define EXT2_BLOCK_TYPES                (0x04)
+
+#define MAXIMUM_RECORD_LENGTH           (0x10000)
+
+#define SECTOR_BITS                     (Vcb->SectorBits)
+#define SECTOR_SIZE                     (Vcb->DiskGeometry.BytesPerSector)
+#define DEFAULT_SECTOR_SIZE             (0x200)
+
+#define SUPER_BLOCK_OFFSET              (0x400)
+#define SUPER_BLOCK_SIZE                (0x400)
+
+#define READ_AHEAD_GRANULARITY          (0x10000)
+
+#define SUPER_BLOCK                     (Vcb->SuperBlock)
+
+#define INODE_SIZE                      (Vcb->InodeSize)
+#define BLOCK_SIZE                      (Vcb->BlockSize)
+#define BLOCK_BITS                      (SUPER_BLOCK->s_log_block_size + 10)
+#define GROUP_DESC_SIZE                 (Vcb->sbi.s_desc_size)
+
+#define INODES_COUNT                    (Vcb->SuperBlock->s_inodes_count)
+
+#define INODES_PER_GROUP                (SUPER_BLOCK->s_inodes_per_group)
+#define BLOCKS_PER_GROUP                (SUPER_BLOCK->s_blocks_per_group)
+#define TOTAL_BLOCKS                    (ext3_blocks_count(SUPER_BLOCK))
+
+#define EXT2_FIRST_DATA_BLOCK           (SUPER_BLOCK->s_first_data_block)
+
+typedef struct ext3_super_block EXT2_SUPER_BLOCK, *PEXT2_SUPER_BLOCK;
+typedef struct ext3_inode EXT2_INODE, *PEXT2_INODE;
+typedef struct ext4_group_desc EXT2_GROUP_DESC, *PEXT2_GROUP_DESC;
+typedef struct ext3_dir_entry EXT2_DIR_ENTRY, *PEXT2_DIR_ENTRY;
+typedef struct ext3_dir_entry_2 EXT2_DIR_ENTRY2, *PEXT2_DIR_ENTRY2;
+
+#define CEILING_ALIGNED(T, A, B) (((A) + (B) - 1) & (~((T)(B) - 1)))
+#define COCKLOFT_ALIGNED(T, A, B) (((A) + (B)) & (~((T)(B) - 1)))
+
+/* File System Releated *************************************************/
+
+#define DRIVER_NAME      "Ext2Fsd"
+#define DEVICE_NAME     L"\\Ext2Fsd"
+#define CDROM_NAME      L"\\Ext2CdFsd"
+
+// Registry
+
+#define PARAMETERS_KEY      L"\\Parameters"
+#define VOLUMES_KEY         L"\\Volumes"
+
+#define READING_ONLY        L"Readonly"
+#define WRITING_SUPPORT     L"WritingSupport"
+#define CHECKING_BITMAP     L"CheckingBitmap"
+#define EXT3_FORCEWRITING   L"Ext3ForceWriting"
+#define CODEPAGE_NAME       L"CodePage"
+#define HIDING_PREFIX       L"HidingPrefix"
+#define HIDING_SUFFIX       L"HidingSuffix"
+#define AUTO_MOUNT          L"AutoMount"
+#define MOUNT_POINT         L"MountPoint"
+
+#define DOS_DEVICE_NAME L"\\DosDevices\\Ext2Fsd"
+
+// To support ext2fsd unload routine
+#if EXT2_UNLOAD
+//
+// Private IOCTL to make the driver ready to unload
+//
+#define IOCTL_PREPARE_TO_UNLOAD \
+CTL_CODE(FILE_DEVICE_UNKNOWN, 2048, METHOD_NEITHER, FILE_WRITE_ACCESS)
+
+#endif // EXT2_UNLOAD
+
+#include "common.h"
+
+#ifndef _GNU_NTIFS_
+typedef IO_STACK_LOCATION EXTENDED_IO_STACK_LOCATION, *PEXTENDED_IO_STACK_LOCATION;
+#endif
+
+#define IsFlagOn(a,b) ((BOOLEAN)(FlagOn(a,b) == b))
+#ifndef FlagOn
+#define FlagOn(_F,_SF)        ((_F) & (_SF))
+#endif
+
+#ifndef BooleanFlagOn
+#define BooleanFlagOn(F,SF)   ((BOOLEAN)(((F) & (SF)) != 0))
+#endif
+
+#ifndef SetFlag
+#define SetFlag(_F,_SF)       ((_F) |= (_SF))
+#endif
+
+#ifndef ClearFlag
+#define ClearFlag(_F,_SF)     ((_F) &= ~(_SF))
+#endif
+
+#ifndef min
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+#endif
+
+#ifndef max
+#define max(a,b) (((a) > (b)) ? (a) : (b))
+#endif
+
+#ifdef _WIN2K_TARGET_
+#define InterlockedOr _InterlockedOr
+LONG
+_InterlockedAnd (
+    IN OUT LONG volatile *Target,
+    IN LONG Set
+);
+
+#pragma intrinsic (_InterlockedAnd)
+#define InterlockedAnd _InterlockedAnd
+
+LONG
+_InterlockedXor (
+    IN OUT LONG volatile *Target,
+    IN LONG Set
+);
+
+#pragma intrinsic (_InterlockedXor)
+#define InterlockedXor _InterlockedXor
+
+#endif  /* only for win2k */
+
+#if EXT2_DEBUG
+
+#define SetLongFlag(_F,_SF)   Ext2SetFlag((PULONG)&(_F), (ULONG)(_SF))
+#define ClearLongFlag(_F,_SF) Ext2ClearFlag((PULONG)&(_F), (ULONG)(_SF))
+
+#ifdef __REACTOS__
+static
+#endif
+__inline
+VOID
+Ext2SetFlag(PULONG Flags, ULONG FlagBit)
+{
+    ULONG _ret = InterlockedOr(Flags, FlagBit);
+    ASSERT(*Flags == (_ret | FlagBit));
+}
+
+#ifdef __REACTOS__
+static
+#endif
+__inline
+VOID
+Ext2ClearFlag(PULONG Flags, ULONG FlagBit)
+{
+    ULONG _ret = InterlockedAnd(Flags, ~FlagBit);
+    ASSERT(*Flags == (_ret & (~FlagBit)));
+}
+
+#else
+
+#define SetLongFlag(_F,_SF)       InterlockedOr(&(_F), (ULONG)(_SF))
+#define ClearLongFlag(_F,_SF)     InterlockedAnd(&(_F), ~((ULONG)(_SF)))
+
+#endif  /* release */
+
+#define Ext2RaiseStatus(IRPCONTEXT,STATUS) {  \
+    (IRPCONTEXT)->ExceptionCode = (STATUS); \
+    ExRaiseStatus((STATUS));                \
+}
+
+#define Ext2NormalizeAndRaiseStatus(IRPCONTEXT,STATUS) {                        \
+    (IRPCONTEXT)->ExceptionCode = STATUS;                                       \
+    if ((STATUS) == STATUS_VERIFY_REQUIRED) { ExRaiseStatus((STATUS)); }        \
+    ExRaiseStatus(FsRtlNormalizeNtstatus((STATUS),STATUS_UNEXPECTED_IO_ERROR)); \
+}
+
+//
+// Define IsWritingToEof for write (append) operations
+//
+
+#define FILE_WRITE_TO_END_OF_FILE       0xffffffff
+
+#define IsWritingToEof(Pos) (((Pos).LowPart == FILE_WRITE_TO_END_OF_FILE) && \
+                             ((Pos).HighPart == -1 ))
+
+#define IsDirectory(Fcb)    IsMcbDirectory((Fcb)->Mcb)
+#define IsSpecialFile(Fcb)  IsMcbSpecialFile((Fcb)->Mcb)
+#define IsSymLink(Fcb)      IsMcbSymLink((Fcb)->Mcb)
+#define IsInodeSymLink(I)   S_ISLNK((I)->i_mode)
+#define IsRoot(Fcb)         IsMcbRoot((Fcb)->Mcb)
+
+//
+// Pool Tags
+//
+
+#define TAG_VPB  ' bpV'
+#define VPB_SIZE sizeof(VPB)
+
+#define EXT2_DATA_MAGIC         'BD2E'
+#define EXT2_INAME_MAGIC        'NI2E'
+#define EXT2_FNAME_MAGIC        'NF2E'
+#define EXT2_VNAME_MAGIC        'NV2E'
+#define EXT2_DENTRY_MAGIC       'ED2E'
+#define EXT2_DIRSP_MAGIC        'SD2E'
+#define EXT2_SB_MAGIC           'BS2E'
+#define EXT2_GD_MAGIC           'DG2E'
+#define EXT2_FLIST_MAGIC        'LF2E'
+#define EXT2_PARAM_MAGIC        'PP2E'
+#define EXT2_RWC_MAGIC          'WR2E'
+
+//
+// Bug Check Codes Definitions
+//
+
+#define EXT2_FILE_SYSTEM   (FILE_SYSTEM)
+
+#define EXT2_BUGCHK_BLOCK               (0x00010000)
+#define EXT2_BUGCHK_CLEANUP             (0x00020000)
+#define EXT2_BUGCHK_CLOSE               (0x00030000)
+#define EXT2_BUGCHK_CMCB                (0x00040000)
+#define EXT2_BUGCHK_CREATE              (0x00050000)
+#define EXT2_BUGCHK_DEBUG               (0x00060000)
+#define EXT2_BUGCHK_DEVCTL              (0x00070000)
+#define EXT2_BUGCHK_DIRCTL              (0x00080000)
+#define EXT2_BUGCHK_DISPATCH            (0x00090000)
+#define EXT2_BUGCHK_EXCEPT              (0x000A0000)
+#define EXT2_BUGCHK_EXT2                (0x000B0000)
+#define EXT2_BUGCHK_FASTIO              (0x000C0000)
+#define EXT2_BUGCHK_FILEINFO            (0x000D0000)
+#define EXT2_BUGCHK_FLUSH               (0x000E0000)
+#define EXT2_BUGCHK_FSCTL               (0x000F0000)
+#define EXT2_BUGCHK_INIT                (0x00100000)
+#define EXT2_BUGCHK_LOCK                (0x0011000)
+#define EXT2_BUGCHK_MEMORY              (0x0012000)
+#define EXT2_BUGCHK_MISC                (0x0013000)
+#define EXT2_BUGCHK_READ                (0x00140000)
+#define EXT2_BUGCHK_SHUTDOWN            (0x00150000)
+#define EXT2_BUGCHK_VOLINFO             (0x00160000)
+#define EXT2_BUGCHK_WRITE               (0x00170000)
+
+#define EXT2_BUGCHK_LAST                (0x00170000)
+
+#define Ext2BugCheck(A,B,C,D) { KeBugCheckEx(EXT2_FILE_SYSTEM, A | __LINE__, B, C, D ); }
+
+
+/* Ext2 file system definions *******************************************/
+
+//
+// The second extended file system magic number
+//
+
+#define EXT2_SUPER_MAGIC        0xEF53
+
+#define EXT2_MIN_BLOCK          1024
+#define EXT2_MIN_FRAG           1024
+#define EXT2_MAX_USER_BLKSIZE   65536
+//
+// Inode flags (Linux uses octad number, but why ? strange!!!)
+//
+
+#define S_IFMT   0x0F000            /* 017 0000 */
+#define S_IFSOCK 0x0C000            /* 014 0000 */
+#define S_IFLNK  0x0A000            /* 012 0000 */
+#define S_IFREG  0x08000            /* 010 0000 */
+#define S_IFBLK  0x06000            /* 006 0000 */
+#define S_IFDIR  0x04000            /* 004 0000 */
+#define S_IFCHR  0x02000            /* 002 0000 */
+#define S_IFIFO  0x01000            /* 001 0000 */
+
+#define S_ISUID  0x00800            /* 000 4000 */
+#define S_ISGID  0x00400            /* 000 2000 */
+#define S_ISVTX  0x00200            /* 000 1000 */
+
+#define S_ISREG(m)      (((m) & S_IFMT) == S_IFREG)
+#define S_ISSOCK(m)     (((m) & S_IFMT) == S_IFSOCK)
+#define S_ISLNK(m)      (((m) & S_IFMT) == S_IFLNK)
+#define S_ISFIL(m)      (((m) & S_IFMT) == S_IFFIL)
+#define S_ISBLK(m)      (((m) & S_IFMT) == S_IFBLK)
+#define S_ISDIR(m)      (((m) & S_IFMT) == S_IFDIR)
+#define S_ISCHR(m)      (((m) & S_IFMT) == S_IFCHR)
+#define S_ISFIFO(m)     (((m) & S_IFMT) == S_IFIFO)
+
+#define S_IPERMISSION_MASK 0x1FF /*  */
+
+#define S_IRWXU  0x1C0              /* 0 0700 */
+#define S_IRWNU  0x180              /* 0 0600 */
+#define S_IRUSR  0x100              /* 0 0400 */
+#define S_IWUSR  0x080              /* 0 0200 */
+#define S_IXUSR  0x040              /* 0 0100 */
+
+#define S_IRWXG  0x038              /* 0 0070 */
+#define S_IRWNG  0x030              /* 0 0060 */
+#define S_IRGRP  0x020              /* 0 0040 */
+#define S_IWGRP  0x010              /* 0 0020 */
+#define S_IXGRP  0x008              /* 0 0010 */
+
+#define S_IRWXO  0x007              /* 0 0007 */
+#define S_IRWNO  0x006              /* 0 0006 */
+#define S_IROTH  0x004              /* 0 0004 */
+#define S_IWOTH  0x002              /* 0 0002 */
+#define S_IXOTH  0x001              /* 0 0001 */
+
+#define S_IRWXUGO   (S_IRWXU|S_IRWXG|S_IRWXO)
+#define S_IALLUGO   (S_ISUID|S_ISGID|S_ISVTX|S_IRWXUGO)
+#define S_IRUGO     (S_IRUSR|S_IRGRP|S_IROTH)
+#define S_IWUGO     (S_IWUSR|S_IWGRP|S_IWOTH)
+#define S_IXUGO     (S_IXUSR|S_IXGRP|S_IXOTH)
+#define S_IFATTR    (S_IRWNU|S_IRWNG|S_IRWNO)
+
+#define S_ISREADABLE(m)    (((m) & S_IPERMISSION_MASK) == (S_IRUSR | S_IRGRP | S_IROTH))
+#define S_ISWRITABLE(m)    (((m) & S_IPERMISSION_MASK) == (S_IWUSR | S_IWGRP | S_IWOTH))
+
+#define Ext2SetReadable(m) do {(m) = (m) | (S_IRUSR | S_IRGRP | S_IROTH);} while(0)
+#define Ext2SetWritable(m) do {(m) = (m) | (S_IWUSR | S_IWGRP | S_IWOTH);} while(0)
+
+#define Ext2SetOwnerWritable(m) do {(m) |= S_IWUSR;} while(0)
+#define Ext2SetOwnerReadOnly(m) do {(m) &= ~S_IWUSR;} while(0)
+
+#define Ext2IsOwnerWritable(m)  (((m) & S_IWUSR) == S_IWUSR)
+#define Ext2IsOwnerReadOnly(m)  (!(Ext2IsOwnerWritable(m)))
+
+#define Ext2SetReadOnly(m) do {(m) &= ~(S_IWUSR | S_IWGRP | S_IWOTH);} while(0)
+
+/*
+ * We need 8-bytes aligned for all the sturctures
+ * It's a must for all ERESOURCE allocations
+ */
+
+//
+// Ext2Fsd Driver Definitions
+//
+
+//
+// EXT2_IDENTIFIER_TYPE
+//
+// Identifiers used to mark the structures
+//
+
+typedef enum _EXT2_IDENTIFIER_TYPE {
+#ifdef _MSC_VER
+    EXT2FGD  = ':DGF',
+    EXT2VCB  = ':BCV',
+    EXT2FCB  = ':BCF',
+    EXT2CCB  = ':BCC',
+    EXT2ICX  = ':XCI',
+    EXT2FSD  = ':DSF',
+    EXT2MCB  = ':BCM'
+#else
+    EXT2FGD  = 0xE2FD0001,
+    EXT2VCB  = 0xE2FD0002,
+    EXT2FCB  = 0xE2FD0003,
+    EXT2CCB  = 0xE2FD0004,
+    EXT2ICX  = 0xE2FD0005,
+    EXT2FSD  = 0xE2FD0006,
+    EXT2MCB  = 0xE2FD0007
+#endif
+} EXT2_IDENTIFIER_TYPE;
+
+//
+// EXT2_IDENTIFIER
+//
+// Header used to mark the structures
+//
+typedef struct _EXT2_IDENTIFIER {
+    EXT2_IDENTIFIER_TYPE     Type;
+    ULONG                    Size;
+} EXT2_IDENTIFIER, *PEXT2_IDENTIFIER;
+
+
+#define NodeType(Ptr) (*((EXT2_IDENTIFIER_TYPE *)(Ptr)))
+
+typedef struct _EXT2_MCB  EXT2_MCB, *PEXT2_MCB;
+
+
+typedef PVOID   PBCB;
+
+//
+
+//
+// EXT2_GLOBAL_DATA
+//
+// Data that is not specific to a mounted volume
+//
+
+typedef struct _EXT2_GLOBAL {
+
+    /* Identifier for this structure */
+    EXT2_IDENTIFIER             Identifier;
+
+    /* Syncronization primitive for this structure */
+    ERESOURCE                   Resource;
+
+    /* Global flags for the driver: I put it since
+       FastIoDispatch isn't 8bytes aligned.  */
+    ULONG                       Flags;
+
+    /* Table of pointers to the fast I/O entry points */
+    FAST_IO_DISPATCH            FastIoDispatch;
+
+    /* Table of pointers to the Cache Manager callbacks */
+    CACHE_MANAGER_CALLBACKS     CacheManagerCallbacks;
+    CACHE_MANAGER_CALLBACKS     CacheManagerNoOpCallbacks;
+
+    /* Pointer to the driver object */
+    PDRIVER_OBJECT              DriverObject;
+
+    /* Pointer to the disk device object */
+    PDEVICE_OBJECT              DiskdevObject;
+
+    /* Pointer to the cdrom device object */
+    PDEVICE_OBJECT              CdromdevObject;
+
+    /* List of mounted volumes */
+    LIST_ENTRY                  VcbList;
+
+    /* Cleaning thread related: resource cleaner */
+    struct {
+        KEVENT                  Engine;
+        KEVENT                  Wait;
+    } Reaper;
+
+    /* Look Aside table of IRP_CONTEXT, FCB, MCB, CCB */
+    NPAGED_LOOKASIDE_LIST       Ext2IrpContextLookasideList;
+    NPAGED_LOOKASIDE_LIST       Ext2FcbLookasideList;
+    NPAGED_LOOKASIDE_LIST       Ext2CcbLookasideList;
+    NPAGED_LOOKASIDE_LIST       Ext2McbLookasideList;
+    NPAGED_LOOKASIDE_LIST       Ext2ExtLookasideList;
+    NPAGED_LOOKASIDE_LIST       Ext2DentryLookasideList;
+    USHORT                      MaxDepth;
+
+    /* User specified global codepage name */
+    struct {
+        UCHAR                   AnsiName[CODEPAGE_MAXLEN];
+        struct nls_table *      PageTable;
+    } Codepage;
+
+    /* global hiding patterns */
+    BOOLEAN                     bHidingPrefix;
+    CHAR                        sHidingPrefix[HIDINGPAT_LEN];
+    BOOLEAN                     bHidingSuffix;
+    CHAR                        sHidingSuffix[HIDINGPAT_LEN];
+
+    /* Registery path */
+    UNICODE_STRING              RegistryPath;
+
+    /* global memory and i/o statistics and memory allocations
+       of various sturctures */
+
+    EXT2_PERF_STATISTICS_V2     PerfStat;
+
+} EXT2_GLOBAL, *PEXT2_GLOBAL;
+
+//
+// Flags for EXT2_GLOBAL_DATA
+//
+
+#define EXT2_UNLOAD_PENDING     0x00000001
+#define EXT2_SUPPORT_WRITING    0x00000002
+#define EXT3_FORCE_WRITING      0x00000004
+#define EXT2_CHECKING_BITMAP    0x00000008
+#define EXT2_AUTO_MOUNT         0x00000010
+
+//
+// Glboal Ext2Fsd Memory Block
+//
+
+extern PEXT2_GLOBAL Ext2Global;
+
+//
+// memory allocation statistics
+//
+
+
+#define INC_MEM_COUNT(_i, _p, _s) do { ASSERT(_p); Ext2TraceMemory(TRUE, (int) (_i), (PVOID)(_p), (LONG)(_s)); } while(0)
+#define DEC_MEM_COUNT(_i, _p, _s) do { ASSERT(_p); Ext2TraceMemory(FALSE, (int) (_i), (PVOID)(_p), (LONG)(_s)); } while(0)
+#define INC_IRP_COUNT(IrpContext) Ext2TraceIrpContext(TRUE, (IrpContext))
+#define DEC_IRP_COUNT(IrpContext) Ext2TraceIrpContext(FALSE, (IrpContext))
+
+//
+// Driver Extension define
+//
+
+#define IsExt2FsDevice(DO) ((DO == Ext2Global->DiskdevObject) || \
+                            (DO == Ext2Global->CdromdevObject) )
+
+#ifdef _WIN2K_TARGET_
+#define  FSRTL_ADVANCED_FCB_HEADER FSRTL_COMMON_FCB_HEADER
+#endif
+
+typedef struct _EXT2_FCBVCB {
+
+    // Command header for Vcb and Fcb
+    FSRTL_ADVANCED_FCB_HEADER   Header;
+
+#ifndef _WIN2K_TARGET_
+    FAST_MUTEX                  Mutex;
+#endif
+
+    // Ext2Fsd identifier
+    EXT2_IDENTIFIER             Identifier;
+
+
+    // Locking resources
+    ERESOURCE                   MainResource;
+    ERESOURCE                   PagingIoResource;
+
+} EXT2_FCBVCB, *PEXT2_FCBVCB;
+
+//
+// EXT2_VCB Volume Control Block
+//
+// Data that represents a mounted logical volume
+// It is allocated as the device extension of the volume device object
+//
+typedef struct _EXT2_VCB {
+
+    /* Common header */
+    EXT2_FCBVCB;
+
+    // Resource for metadata (super block, tables)
+    ERESOURCE                   MetaLock;
+
+    // Resource for Mcb (Meta data control block)
+    ERESOURCE                   McbLock;
+
+    // Entry of Mcb Tree (Root Node)
+    PEXT2_MCB                   McbTree;
+
+    // Mcb list
+    LIST_ENTRY                  McbList;
+    ULONG                       NumOfMcb;
+
+    // Link list to Global
+    LIST_ENTRY                  Next;
+
+    // Section objects
+    SECTION_OBJECT_POINTERS     SectionObject;
+
+    // Dirty Mcbs of modifications for volume stream
+    LARGE_MCB                   Extents;
+
+    // List of FCBs for open files on this volume
+    ULONG                       FcbCount;
+    LIST_ENTRY                  FcbList;
+    KSPIN_LOCK                  FcbLock;
+
+    // Share Access for the file object
+    SHARE_ACCESS                ShareAccess;
+
+    // Incremented on IRP_MJ_CREATE, decremented on IRP_MJ_CLOSE
+    // for both files on this volume and open instances of the
+    // volume itself.
+    ULONG                       ReferenceCount;     /* total ref count */
+    ULONG                       OpenHandleCount;    /* all handles */
+
+    ULONG                       OpenVolumeCount;    /* volume handle */
+
+    // Disk change count
+    ULONG                       ChangeCount;
+
+    // Pointer to the VPB in the target device object
+    PVPB                        Vpb;
+    PVPB                        Vpb2;
+
+    // The FileObject of Volume used to lock the volume
+    PFILE_OBJECT                LockFile;
+
+    // List of IRPs pending on directory change notify requests
+    LIST_ENTRY                  NotifyList;
+
+    // Pointer to syncronization primitive for this list
+    PNOTIFY_SYNC                NotifySync;
+
+    // This volumes device object
+    PDEVICE_OBJECT              DeviceObject;
+
+    // The physical device object (the disk)
+    PDEVICE_OBJECT              TargetDeviceObject;
+
+    // The physical device object (the disk)
+    PDEVICE_OBJECT              RealDevice;
+
+    // Information about the physical device object
+    DISK_GEOMETRY               DiskGeometry;
+    PARTITION_INFORMATION       PartitionInformation;
+
+    BOOLEAN                     IsExt3fs;
+    PEXT2_SUPER_BLOCK           SuperBlock;
+
+    /*
+        // Bitmap Block per group
+        PRTL_BITMAP                 BlockBitMaps;
+        PRTL_BITMAP                 InodeBitMaps;
+    */
+
+    // Block / Cluster size
+    ULONG                       BlockSize;
+
+    // Sector size in bits
+    ULONG                       SectorBits;
+
+    // Aligned size (Page or Block)
+    ULONGLONG                   IoUnitSize;
+
+    // Bits of aligned size
+    ULONG                       IoUnitBits;
+
+    // Inode size
+    ULONG                       InodeSize;
+
+    // Inode lookaside list
+    NPAGED_LOOKASIDE_LIST       InodeLookasideList;
+
+    // Flags for the volume
+    ULONG                       Flags;
+
+    // Streaming File Object
+    PFILE_OBJECT                Volume;
+
+    // User specified codepage name per volume
+    struct {
+        UCHAR                   AnsiName[CODEPAGE_MAXLEN];
+        struct nls_table *      PageTable;
+    } Codepage;
+
+    /* patterns to hiding files */
+    BOOLEAN                     bHidingPrefix;
+    CHAR                        sHidingPrefix[HIDINGPAT_LEN];
+    BOOLEAN                     bHidingSuffix;
+    CHAR                        sHidingSuffix[HIDINGPAT_LEN];
+
+    /* mountpoint: symlink to DesDevices */
+    UCHAR                       DrvLetter;
+
+    struct block_device         bd;
+    struct super_block          sb;
+    struct ext3_sb_info         sbi;
+
+    /* Maximum file size in blocks ... */
+    ULONG                       max_blocks_per_layer[EXT2_BLOCK_TYPES];
+    ULONG                       max_data_blocks;
+    loff_t                      max_bitmap_bytes;
+    loff_t                      max_bytes;
+} EXT2_VCB, *PEXT2_VCB;
+
+//
+// Flags for EXT2_VCB
+//
+#define VCB_INITIALIZED         0x00000001
+#define VCB_VOLUME_LOCKED       0x00000002
+#define VCB_MOUNTED             0x00000004
+#define VCB_DISMOUNT_PENDING    0x00000008
+#define VCB_NEW_VPB             0x00000010
+#define VCB_BEING_CLOSED        0x00000020
+
+#define VCB_FORCE_WRITING       0x00004000
+#define VCB_DEVICE_REMOVED      0x00008000
+#define VCB_JOURNAL_RECOVER     0x00080000
+#define VCB_ARRIVAL_NOTIFIED    0x00800000
+#define VCB_READ_ONLY           0x08000000
+#define VCB_WRITE_PROTECTED     0x10000000
+#define VCB_FLOPPY_DISK         0x20000000
+#define VCB_REMOVAL_PREVENTED   0x40000000
+#define VCB_REMOVABLE_MEDIA     0x80000000
+
+
+#define IsVcbInited(Vcb)   (IsFlagOn((Vcb)->Flags, VCB_INITIALIZED))
+#define IsMounted(Vcb)     (IsFlagOn((Vcb)->Flags, VCB_MOUNTED))
+#define IsDispending(Vcb)  (IsFlagOn((Vcb)->Flags, VCB_DISMOUNT_PENDING))
+#define IsVcbReadOnly(Vcb) (IsFlagOn((Vcb)->Flags, VCB_READ_ONLY) ||    \
+                            IsFlagOn((Vcb)->Flags, VCB_WRITE_PROTECTED))
+
+
+#define IsExt3ForceWrite()   (IsFlagOn(Ext2Global->Flags, EXT3_FORCE_WRITING))
+#define IsVcbForceWrite(Vcb) (IsFlagOn((Vcb)->Flags, VCB_FORCE_WRITING))
+#define CanIWrite(Vcb)       (IsExt3ForceWrite() || (!IsVcbReadOnly(Vcb) && IsVcbForceWrite(Vcb)))
+#define IsLazyWriter(Fcb)    ((Fcb)->LazyWriterThread == PsGetCurrentThread())
+//
+// EXT2_FCB File Control Block
+//
+// Data that represents an open file
+// There is a single instance of the FCB for every open file
+//
+typedef struct _EXT2_FCB {
+
+    /* Common header */
+    EXT2_FCBVCB;
+
+    // List of FCBs for this volume
+    LIST_ENTRY                      Next;
+
+    SECTION_OBJECT_POINTERS         SectionObject;
+
+    // Share Access for the file object
+    SHARE_ACCESS                    ShareAccess;
+
+    // List of byte-range locks for this file
+    FILE_LOCK                       FileLockAnchor;
+
+    // oplock information management structure
+    OPLOCK                          Oplock;
+
+    // Lazy writer thread context
+    PETHREAD                        LazyWriterThread;
+
+    // Incremented on IRP_MJ_CREATE, decremented on IRP_MJ_CLEANUP
+    ULONG                           OpenHandleCount;
+
+    // Incremented on IRP_MJ_CREATE, decremented on IRP_MJ_CLOSE
+    ULONG                           ReferenceCount;
+
+    // Incremented on IRP_MJ_CREATE, decremented on IRP_MJ_CLEANUP
+    // But only for Files with FO_NO_INTERMEDIATE_BUFFERING flag
+    ULONG                           NonCachedOpenCount;
+
+    // Flags for the FCB
+    ULONG                           Flags;
+
+    // Pointer to the inode
+    struct inode                   *Inode;
+
+    // Vcb
+    PEXT2_VCB                       Vcb;
+
+    // Mcb Node ...
+    PEXT2_MCB                       Mcb;
+
+} EXT2_FCB, *PEXT2_FCB;
+
+//
+// Flags for EXT2_FCB
+//
+
+#define FCB_FROM_POOL               0x00000001
+#define FCB_PAGE_FILE               0x00000002
+#define FCB_FILE_MODIFIED           0x00000020
+#define FCB_STATE_BUSY              0x00000040
+#define FCB_ALLOC_IN_CREATE         0x00000080
+#define FCB_ALLOC_IN_WRITE          0x00000100
+#define FCB_ALLOC_IN_SETINFO        0x00000200
+
+#define FCB_DELETE_PENDING          0x80000000
+
+//
+// Mcb Node
+//
+
+struct _EXT2_MCB {
+
+    // Identifier for this structure
+    EXT2_IDENTIFIER                 Identifier;
+
+    // Flags
+    ULONG                           Flags;
+
+    // Link List Info
+    PEXT2_MCB                       Parent; // Parent
+    PEXT2_MCB                       Next;   // Brothers
+
+    union {
+        PEXT2_MCB                   Child;  // Children Mcb nodes
+        PEXT2_MCB                   Target; // Target Mcb of symlink
+    };
+
+    // Mcb Node Info
+
+    // -> Fcb
+    PEXT2_FCB                       Fcb;
+
+    // Short name
+    UNICODE_STRING                  ShortName;
+
+    // Full name with path
+    UNICODE_STRING                  FullName;
+
+    // File attribute
+    ULONG                           FileAttr;
+
+    // reference count
+    ULONG                           Refercount;
+
+    // Extents zone
+    LARGE_MCB                       Extents;
+
+       // Metablocks
+    LARGE_MCB                       MetaExts;
+
+    // Time stamps
+    LARGE_INTEGER                   CreationTime;
+    LARGE_INTEGER                   LastWriteTime;
+    LARGE_INTEGER                   ChangeTime;
+    LARGE_INTEGER                   LastAccessTime;
+
+    // List Link to Vcb->McbList
+    LIST_ENTRY                      Link;
+
+    struct inode                    Inode;
+    struct dentry                  *de;
+};
+
+//
+// Flags for MCB
+//
+#define MCB_FROM_POOL               0x00000001
+#define MCB_VCB_LINK                0x00000002
+#define MCB_ENTRY_TREE              0x00000004
+#define MCB_FILE_DELETED            0x00000008
+
+#define MCB_ZONE_INITED             0x20000000
+#define MCB_TYPE_SPECIAL            0x40000000  /* unresolved symlink + device node */
+#define MCB_TYPE_SYMLINK            0x80000000
+
+#define IsMcbUsed(Mcb)          ((Mcb)->Refercount > 0)
+#define IsMcbSymLink(Mcb)       IsFlagOn((Mcb)->Flags, MCB_TYPE_SYMLINK)
+#define IsZoneInited(Mcb)       IsFlagOn((Mcb)->Flags, MCB_ZONE_INITED)
+#define IsMcbSpecialFile(Mcb)   IsFlagOn((Mcb)->Flags, MCB_TYPE_SPECIAL)
+#define IsMcbRoot(Mcb)          ((Mcb)->Inode.i_ino == EXT2_ROOT_INO)
+#define IsMcbReadonly(Mcb)      IsFlagOn((Mcb)->FileAttr, FILE_ATTRIBUTE_READONLY)
+#define IsMcbDirectory(Mcb)     IsFlagOn((Mcb)->FileAttr, FILE_ATTRIBUTE_DIRECTORY)
+#define IsFileDeleted(Mcb)      IsFlagOn((Mcb)->Flags, MCB_FILE_DELETED)
+
+#define IsLinkInvalid(Mcb)      (IsMcbSymLink(Mcb) && IsFileDeleted(Mcb->Target))
+
+/*
+ * routines for reference count management
+ */
+
+#define Ext2ReferXcb(_C)  InterlockedIncrement(_C)
+#define Ext2DerefXcb(_C)  DEC_OBJ_CNT(_C)
+
+#ifdef __REACTOS__
+static
+#endif
+__inline ULONG DEC_OBJ_CNT(PULONG _C) {
+    if (*_C > 0) {
+        return InterlockedDecrement(_C);
+    } else {
+        DbgBreak();
+    }
+    return 0;
+}
+
+#if EXT2_DEBUG
+VOID
+Ext2TraceMcb(PCHAR fn, USHORT lc, USHORT add, PEXT2_MCB Mcb);
+#define Ext2ReferMcb(Mcb) Ext2TraceMcb(__FUNCTION__, __LINE__, TRUE, Mcb)
+#define Ext2DerefMcb(Mcb) Ext2TraceMcb(__FUNCTION__, __LINE__, FALSE, Mcb)
+#else
+#define Ext2ReferMcb(Mcb) Ext2ReferXcb(&Mcb->Refercount)
+#define Ext2DerefMcb(Mcb) Ext2DerefXcb(&Mcb->Refercount)
+#endif
+
+//
+// EXT2_CCB Context Control Block
+//
+// Data that represents one instance of an open file
+// There is one instance of the CCB for every instance of an open file
+//
+typedef struct _EXT2_CCB {
+
+    // Identifier for this structure
+    EXT2_IDENTIFIER     Identifier;
+
+    // Flags
+    ULONG               Flags;
+
+    // Mcb of it's symbol link
+    PEXT2_MCB           SymLink;
+
+    // State that may need to be maintained
+    UNICODE_STRING      DirectorySearchPattern;
+
+    /* Open handle control block */
+    struct file         filp;
+
+} EXT2_CCB, *PEXT2_CCB;
+
+//
+// Flags for CCB
+//
+
+#define CCB_FROM_POOL               0x00000001
+#define CCB_VOLUME_DASD_PURGE       0x00000002
+#define CCB_LAST_WRITE_UPDATED      0x00000004
+
+#define CCB_DELETE_ON_CLOSE         0x00000010
+
+#define CCB_ALLOW_EXTENDED_DASD_IO  0x80000000
+
+//
+// EXT2_IRP_CONTEXT
+//
+// Used to pass information about a request between the drivers functions
+//
+typedef struct ext2_icb {
+
+    // Identifier for this structure
+    EXT2_IDENTIFIER     Identifier;
+
+    // Pointer to the IRP this request describes
+    PIRP                Irp;
+
+    // Flags
+    ULONG               Flags;
+
+    // The major and minor function code for the request
+    UCHAR               MajorFunction;
+    UCHAR               MinorFunction;
+
+    // The device object
+    PDEVICE_OBJECT      DeviceObject;
+
+    // The real device object
+    PDEVICE_OBJECT      RealDevice;
+
+    // The file object
+    PFILE_OBJECT        FileObject;
+
+    PEXT2_FCB           Fcb;
+    PEXT2_CCB           Ccb;
+
+    // If the request is top level
+    BOOLEAN             IsTopLevel;
+
+    // Used if the request needs to be queued for later processing
+    WORK_QUEUE_ITEM     WorkQueueItem;
+
+    // If an exception is currently in progress
+    BOOLEAN             ExceptionInProgress;
+
+    // The exception code when an exception is in progress
+    NTSTATUS            ExceptionCode;
+
+} EXT2_IRP_CONTEXT, *PEXT2_IRP_CONTEXT;
+
+
+#define IRP_CONTEXT_FLAG_FROM_POOL       (0x00000001)
+#define IRP_CONTEXT_FLAG_WAIT            (0x00000002)
+#define IRP_CONTEXT_FLAG_WRITE_THROUGH   (0x00000004)
+#define IRP_CONTEXT_FLAG_FLOPPY          (0x00000008)
+#define IRP_CONTEXT_FLAG_DISABLE_POPUPS  (0x00000020)
+#define IRP_CONTEXT_FLAG_DEFERRED        (0x00000040)
+#define IRP_CONTEXT_FLAG_VERIFY_READ     (0x00000080)
+#define IRP_CONTEXT_STACK_IO_CONTEXT     (0x00000100)
+#define IRP_CONTEXT_FLAG_REQUEUED        (0x00000200)
+#define IRP_CONTEXT_FLAG_USER_IO         (0x00000400)
+#define IRP_CONTEXT_FLAG_DELAY_CLOSE     (0x00000800)
+#define IRP_CONTEXT_FLAG_FILE_BUSY       (0x00001000)
+
+
+#define Ext2CanIWait() (!IrpContext || IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT))
+
+//
+// EXT2_ALLOC_HEADER
+//
+// In the checked version of the driver this header is put in the beginning of
+// every memory allocation
+//
+typedef struct _EXT2_ALLOC_HEADER {
+    EXT2_IDENTIFIER Identifier;
+} EXT2_ALLOC_HEADER, *PEXT2_ALLOC_HEADER;
+
+typedef struct _FCB_LIST_ENTRY {
+    PEXT2_FCB    Fcb;
+    LIST_ENTRY   Next;
+} FCB_LIST_ENTRY, *PFCB_LIST_ENTRY;
+
+
+// Block Description List
+typedef struct _EXT2_EXTENT {
+    LONGLONG    Lba;
+    ULONG       Offset;
+    ULONG       Length;
+    PIRP        Irp;
+    struct _EXT2_EXTENT * Next;
+} EXT2_EXTENT, *PEXT2_EXTENT;
+
+
+/* FUNCTIONS DECLARATION *****************************************************/
+
+// Include this so we don't need the latest WDK to build the driver.
+#ifndef FSCTL_GET_RETRIEVAL_POINTER_BASE
+#define FSCTL_GET_RETRIEVAL_POINTER_BASE    CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 141, METHOD_BUFFERED, FILE_ANY_ACCESS) // RETRIEVAL_POINTER_BASE
+#endif
+
+//
+//  The following macro is used to determine if an FSD thread can block
+//  for I/O or wait for a resource.  It returns TRUE if the thread can
+//  block and FALSE otherwise.  This attribute can then be used to call
+//  the FSD & FSP common work routine with the proper wait value.
+//
+
+#define CanExt2Wait(IRP) IoIsOperationSynchronous(Irp)
+
+//
+// memory allocation statistics
+//
+
+#ifdef __REACTOS__
+static
+#endif
+__inline
+VOID
+Ext2TraceMemory(BOOLEAN _n, int _i, PVOID _p, LONG _s)
+{
+    if (_n) {
+        InterlockedIncrement(&Ext2Global->PerfStat.Current.Slot[_i]);
+        InterlockedIncrement(&Ext2Global->PerfStat.Total.Slot[_i]);
+        InterlockedExchangeAdd(&Ext2Global->PerfStat.Size.Slot[_i], _s);
+    } else {
+        InterlockedDecrement(&Ext2Global->PerfStat.Current.Slot[_i]);
+        InterlockedExchangeAdd(&Ext2Global->PerfStat.Size.Slot[_i], -1 * _s);
+    }
+}
+
+#ifdef __REACTOS__
+static
+#endif
+__inline
+VOID
+Ext2TraceIrpContext(BOOLEAN _n, PEXT2_IRP_CONTEXT IrpContext)
+{
+    if (_n) {
+        INC_MEM_COUNT(PS_IRP_CONTEXT, IrpContext, sizeof(EXT2_IRP_CONTEXT));
+        InterlockedIncrement(&(Ext2Global->PerfStat.Irps[IrpContext->MajorFunction].Current));
+    } else {
+        DEC_MEM_COUNT(PS_IRP_CONTEXT, IrpContext, sizeof(EXT2_IRP_CONTEXT));
+        InterlockedIncrement(&Ext2Global->PerfStat.Irps[IrpContext->MajorFunction].Processed);
+        InterlockedDecrement(&Ext2Global->PerfStat.Irps[IrpContext->MajorFunction].Current);
+    }
+}
+
+typedef struct _EXT2_FILLDIR_CONTEXT {
+    PEXT2_IRP_CONTEXT       efc_irp;
+    PUCHAR                  efc_buf;
+    ULONG                   efc_size;
+    ULONG                   efc_start;
+    ULONG                   efc_prev;
+    NTSTATUS                efc_status;
+    FILE_INFORMATION_CLASS  efc_fi;
+    BOOLEAN                 efc_single;
+} EXT2_FILLDIR_CONTEXT, *PEXT2_FILLDIR_CONTEXT;
+
+//
+// Block.c
+//
+
+PMDL
+Ext2CreateMdl (
+    IN PVOID Buffer,
+    IN BOOLEAN bPaged,
+    IN ULONG Length,
+    IN LOCK_OPERATION Operation
+);
+
+VOID
+Ext2DestroyMdl (IN PMDL Mdl);
+
+NTSTATUS
+Ext2LockUserBuffer (
+    IN PIRP             Irp,
+    IN ULONG            Length,
+    IN LOCK_OPERATION   Operation);
+PVOID
+Ext2GetUserBuffer (IN PIRP Irp);
+
+
+NTSTATUS
+Ext2ReadWriteBlocks(
+    IN PEXT2_IRP_CONTEXT IrpContext,
+    IN PEXT2_VCB        Vcb,
+    IN PEXT2_EXTENT     Extent,
+    IN ULONG            Length
+    );
+
+NTSTATUS
+Ext2ReadSync(
+    IN PEXT2_VCB        Vcb,
+    IN ULONGLONG        Offset,
+    IN ULONG            Length,
+    OUT PVOID           Buffer,
+    IN BOOLEAN          bVerify );
+
+NTSTATUS
+Ext2ReadDisk(
+    IN PEXT2_VCB       Vcb,
+    IN ULONGLONG       Offset,
+    IN ULONG           Size,
+    IN PVOID           Buffer,
+    IN BOOLEAN         bVerify  );
+
+NTSTATUS
+Ext2DiskIoControl (
+    IN PDEVICE_OBJECT   DeviceOjbect,
+    IN ULONG            IoctlCode,
+    IN PVOID            InputBuffer,
+    IN ULONG            InputBufferSize,
+    IN OUT PVOID        OutputBuffer,
+    IN OUT PULONG       OutputBufferSize );
+
+VOID
+Ext2MediaEjectControl (
+    IN PEXT2_IRP_CONTEXT IrpContext,
+    IN PEXT2_VCB Vcb,
+    IN BOOLEAN bPrevent );
+
+NTSTATUS
+Ext2DiskShutDown(PEXT2_VCB Vcb);
+
+
+//
+// Cleanup.c
+//
+
+NTSTATUS
+Ext2Cleanup (IN PEXT2_IRP_CONTEXT IrpContext);
+
+//
+// Close.c
+//
+
+NTSTATUS
+Ext2Close (IN PEXT2_IRP_CONTEXT IrpContext);
+
+VOID
+Ext2QueueCloseRequest (IN PEXT2_IRP_CONTEXT IrpContext);
+
+VOID NTAPI
+Ext2DeQueueCloseRequest (IN PVOID Context);
+
+//
+// Cmcb.c
+//
+
+BOOLEAN NTAPI
+Ext2AcquireForLazyWrite (
+    IN PVOID    Context,
+    IN BOOLEAN  Wait );
+VOID NTAPI
+Ext2ReleaseFromLazyWrite (IN PVOID Context);
+
+BOOLEAN NTAPI
+Ext2AcquireForReadAhead (
+    IN PVOID    Context,
+    IN BOOLEAN  Wait );
+
+VOID NTAPI
+Ext2ReleaseFromReadAhead (IN PVOID Context);
+
+BOOLEAN NTAPI
+Ext2NoOpAcquire (
+    IN PVOID Fcb,
+    IN BOOLEAN Wait );
+
+VOID NTAPI
+Ext2NoOpRelease (IN PVOID Fcb);
+
+VOID NTAPI
+Ext2AcquireForCreateSection (
+    IN PFILE_OBJECT FileObject
+);
+
+VOID NTAPI
+Ext2ReleaseForCreateSection (
+    IN PFILE_OBJECT FileObject
+);
+
+NTSTATUS NTAPI
+Ext2AcquireFileForModWrite (
+    IN PFILE_OBJECT FileObject,
+    IN PLARGE_INTEGER EndingOffset,
+    OUT PERESOURCE *ResourceToRelease,
+    IN PDEVICE_OBJECT DeviceObject
+);
+
+NTSTATUS NTAPI
+Ext2ReleaseFileForModWrite (
+    IN PFILE_OBJECT FileObject,
+    IN PERESOURCE ResourceToRelease,
+    IN PDEVICE_OBJECT DeviceObject
+);
+
+NTSTATUS NTAPI
+Ext2AcquireFileForCcFlush (
+    IN PFILE_OBJECT FileObject,
+    IN PDEVICE_OBJECT DeviceObject
+);
+
+NTSTATUS NTAPI
+Ext2ReleaseFileForCcFlush (
+    IN PFILE_OBJECT FileObject,
+    IN PDEVICE_OBJECT DeviceObject
+);
+
+
+//
+// Create.c
+//
+
+
+BOOLEAN
+Ext2IsNameValid(PUNICODE_STRING FileName);
+
+NTSTATUS
+Ext2FollowLink (
+    IN PEXT2_IRP_CONTEXT    IrpContext,
+    IN PEXT2_VCB            Vcb,
+    IN PEXT2_MCB            Parent,
+    IN PEXT2_MCB            Mcb,
+    IN USHORT               Linkdep
+);
+
+NTSTATUS
+Ext2ScanDir (
+    IN PEXT2_IRP_CONTEXT    IrpContext,
+    IN PEXT2_VCB            Vcb,
+    IN PEXT2_MCB            Parent,
+    IN PUNICODE_STRING      FileName,
+    OUT PULONG              Inode,
+    struct dentry         **dentry
+);
+
+BOOLEAN
+Ext2IsSpecialSystemFile(
+    IN PUNICODE_STRING FileName,
+    IN BOOLEAN         bDirectory
+);
+
+NTSTATUS
+Ext2LookupFile (
+    IN PEXT2_IRP_CONTEXT    IrpContext,
+    IN PEXT2_VCB            Vcb,
+    IN PUNICODE_STRING      FullName,
+    IN PEXT2_MCB            Parent,
+    OUT PEXT2_MCB *         Ext2Mcb,
+    IN USHORT               Linkdep
+);
+
+NTSTATUS
+Ext2CreateFile(
+    IN PEXT2_IRP_CONTEXT IrpContext,
+    IN PEXT2_VCB Vcb,
+    OUT PBOOLEAN OpPostIrp
+);
+
+NTSTATUS
+Ext2CreateVolume(
+    IN PEXT2_IRP_CONTEXT IrpContext,
+    IN PEXT2_VCB Vcb );
+
+NTSTATUS
+Ext2Create (IN PEXT2_IRP_CONTEXT IrpContext);
+
+NTSTATUS
+Ext2CreateInode(
+    IN PEXT2_IRP_CONTEXT   IrpContext,
+    IN PEXT2_VCB           Vcb,
+    IN PEXT2_FCB           pParentFcb,
+    IN ULONG               Type,
+    IN ULONG               FileAttr,
+    IN PUNICODE_STRING     FileName);
+
+
+NTSTATUS
+Ext2SupersedeOrOverWriteFile(
+    IN PEXT2_IRP_CONTEXT IrpContext,
+    IN PFILE_OBJECT      FileObject,
+    IN PEXT2_VCB         Vcb,
+    IN PEXT2_FCB         Fcb,
+    IN PLARGE_INTEGER    AllocationSize,
+    IN ULONG             Disposition
+);
+
+//
+// Debug.c
+//
+
+/* debug levels */
+#define DL_NVR 0
+#define DL_VIT 0x00000001
+#define DL_ERR 0x00000002
+#define DL_DBG 0x00000004
+#define DL_INF 0x00000008
+#define DL_FUN 0x00000010
+#define DL_LOW 0x00000020
+#define DL_REN 0x00000040   /* renaming operation */
+#define DL_RES 0x00000080   /* entry reference managment */
+#define DL_BLK 0x00000100   /* data block allocation / free */
+#define DL_CP  0x00000200   /* code pages (create, querydir) */
+#define DL_EXT 0x00000400   /* mcb extents */
+#define DL_MAP 0x00000800   /* retrieval points */
+#define DL_JNL 0x00001000   /* dump journal operations */
+#define DL_HTI 0x00002000   /* htree index */
+#define DL_WRN 0x00004000   /* warning */
+#define DL_BH  0x00008000   /* buffer head */
+#define DL_PNP 0x00010000   /* pnp */
+#define DL_IO  0x00020000   /* file i/o */
+
+#define DL_ALL (DL_ERR|DL_VIT|DL_DBG|DL_INF|DL_FUN|DL_LOW|DL_REN|DL_RES|DL_BLK|DL_CP|DL_EXT|DL_MAP|DL_JNL|DL_HTI|DL_WRN|DL_BH|DL_PNP|DL_IO)
+
+#if EXT2_DEBUG && defined(__REACTOS__)
+  #define DL_DEFAULT (DL_ERR|DL_VIT|DL_DBG|DL_INF|DL_FUN|DL_LOW|DL_WRN)
+#else
+  #define DL_DEFAULT (DL_ERR|DL_VIT)
+#endif
+
+#if EXT2_DEBUG
+extern  ULONG DebugFilter;
+
+VOID
+__cdecl
+Ext2NiPrintf(
+    PCHAR DebugMessage,
+    ...
+);
+
+#define DEBUG(_DL, arg)    do {if ((_DL) & DebugFilter) Ext2Printf arg;} while(0)
+#define DEBUGNI(_DL, arg)  do {if ((_DL) & DebugFilter) Ext2NiPrintf arg;} while(0)
+
+#define Ext2CompleteRequest(Irp, bPrint, PriorityBoost) \
+        Ext2DbgPrintComplete(Irp, bPrint); \
+        IoCompleteRequest(Irp, PriorityBoost)
+
+#else
+
+#define DEBUG(_DL, arg) do {if ((_DL) & DL_ERR) DbgPrint arg;} while(0)
+
+#define Ext2CompleteRequest(Irp, bPrint, PriorityBoost) \
+        IoCompleteRequest(Irp, PriorityBoost)
+
+#endif // EXT2_DEBUG
+
+VOID
+__cdecl
+Ext2Printf(
+    PCHAR DebugMessage,
+    ...
+);
+
+extern ULONG ProcessNameOffset;
+
+#define Ext2GetCurrentProcessName() ( \
+    (PUCHAR) PsGetCurrentProcess() + ProcessNameOffset \
+)
+
+ULONG
+Ext2GetProcessNameOffset (VOID);
+
+VOID
+Ext2DbgPrintCall (
+    IN PDEVICE_OBJECT   DeviceObject,
+    IN PIRP             Irp );
+
+VOID
+Ext2DbgPrintComplete (
+    IN PIRP Irp,
+    IN BOOLEAN bPrint
+);
+
+PUCHAR
+Ext2NtStatusToString (IN NTSTATUS Status );
+
+PVOID Ext2AllocatePool(
+    IN POOL_TYPE PoolType,
+    IN SIZE_T NumberOfBytes,
+    IN ULONG Tag
+);
+
+VOID
+Ext2FreePool(
+    IN PVOID P,
+    IN ULONG Tag
+);
+
+//
+// Devctl.c
+//
+
+NTSTATUS
+Ext2ProcessGlobalProperty(
+    IN  PDEVICE_OBJECT  DeviceObject,
+    IN  PEXT2_VOLUME_PROPERTY2 Property,
+    IN  ULONG Length
+);
+
+NTSTATUS
+Ext2ProcessVolumeProperty(
+    IN  PEXT2_VCB              Vcb,
+    IN  PEXT2_VOLUME_PROPERTY2 Property,
+    IN  ULONG Length
+);
+
+NTSTATUS
+Ext2ProcessUserProperty(
+    IN PEXT2_IRP_CONTEXT        IrpContext,
+    IN PEXT2_VOLUME_PROPERTY2   Property,
+    IN ULONG                    Length
+);
+
+NTSTATUS
+Ex2ProcessUserPerfStat(
+    IN PEXT2_IRP_CONTEXT        IrpContext,
+    IN PEXT2_QUERY_PERFSTAT     QueryPerf,
+    IN ULONG                    Length
+);
+
+NTSTATUS
+Ex2ProcessMountPoint(
+    IN PEXT2_IRP_CONTEXT        IrpContext,
+    IN PEXT2_MOUNT_POINT        MountPoint,
+    IN ULONG                    Length
+);
+
+NTSTATUS
+Ext2DeviceControlNormal (IN PEXT2_IRP_CONTEXT IrpContext);
+
+NTSTATUS
+Ext2PrepareToUnload (IN PEXT2_IRP_CONTEXT IrpContext);
+
+NTSTATUS
+Ext2DeviceControl (IN PEXT2_IRP_CONTEXT IrpContext);
+
+//
+// Dirctl.c
+//
+
+ULONG
+Ext2GetInfoLength(IN FILE_INFORMATION_CLASS  FileInformationClass);
+
+NTSTATUS
+Ext2ProcessEntry(
+    IN PEXT2_IRP_CONTEXT    IrpContext,
+    IN PEXT2_VCB            Vcb,
+    IN PEXT2_FCB            Dcb,
+    IN FILE_INFORMATION_CLASS  FileInformationClass,
+    IN ULONG                in,
+    IN PVOID                Buffer,
+    IN ULONG                UsedLength,
+    IN ULONG                Length,
+    IN ULONG                FileIndex,
+    IN PUNICODE_STRING      pName,
+    OUT PULONG              EntrySize,
+    IN BOOLEAN              Single
+);
+
+BOOLEAN
+Ext2IsWearingCloak(
+    IN  PEXT2_VCB       Vcb,
+    IN  POEM_STRING     OeName
+);
+
+NTSTATUS Ext2QueryDirectory (IN PEXT2_IRP_CONTEXT IrpContext);
+
+NTSTATUS
+Ext2NotifyChangeDirectory (
+    IN PEXT2_IRP_CONTEXT IrpContext
+);
+
+VOID
+Ext2NotifyReportChange (
+    IN PEXT2_IRP_CONTEXT IrpContext,
+    IN PEXT2_VCB         Vcb,
+    IN PEXT2_MCB         Mcb,
+    IN ULONG             Filter,
+    IN ULONG             Action
+);
+
+NTSTATUS
+Ext2DirectoryControl (IN PEXT2_IRP_CONTEXT IrpContext);
+
+BOOLEAN
+Ext2IsDirectoryEmpty (
+    IN PEXT2_IRP_CONTEXT IrpContext,
+    IN PEXT2_VCB Vcb,
+    IN PEXT2_MCB Mcb
+);
+
+//
+// Dispatch.c
+//
+
+VOID NTAPI
+Ext2OplockComplete (
+    IN PVOID Context,
+    IN PIRP Irp
+);
+
+VOID NTAPI
+Ext2LockIrp (
+    IN PVOID Context,
+    IN PIRP Irp
+);
+
+NTSTATUS
+Ext2QueueRequest (IN PEXT2_IRP_CONTEXT IrpContext);
+
+VOID NTAPI
+Ext2DeQueueRequest (IN PVOID Context);
+
+NTSTATUS
+Ext2DispatchRequest (IN PEXT2_IRP_CONTEXT IrpContext);
+
+NTSTATUS NTAPI
+Ext2BuildRequest (
+    IN PDEVICE_OBJECT   DeviceObject,
+    IN PIRP             Irp
+);
+
+//
+// Except.c
+//
+
+NTSTATUS
+Ext2ExceptionFilter (
+    IN PEXT2_IRP_CONTEXT    IrpContext,
+    IN PEXCEPTION_POINTERS ExceptionPointer
+);
+
+NTSTATUS
+Ext2ExceptionHandler (IN PEXT2_IRP_CONTEXT IrpContext);
+
+
+//
+// Extents.c
+//
+
+
+NTSTATUS
+Ext2MapExtent(
+    IN PEXT2_IRP_CONTEXT    IrpContext,
+    IN PEXT2_VCB            Vcb,
+    IN PEXT2_MCB            Mcb,
+    IN ULONG                Index,
+    IN BOOLEAN              Alloc,
+    OUT PULONG              Block,
+    OUT PULONG              Number
+    );
+
+NTSTATUS
+Ext2ExpandExtent(
+    PEXT2_IRP_CONTEXT IrpContext,
+    PEXT2_VCB         Vcb,
+    PEXT2_MCB         Mcb,
+    ULONG             Start,
+    ULONG             End,
+    PLARGE_INTEGER    Size
+    );
+
+NTSTATUS
+Ext2TruncateExtent(
+    PEXT2_IRP_CONTEXT IrpContext,
+    PEXT2_VCB         Vcb,
+    PEXT2_MCB         Mcb,
+    PLARGE_INTEGER    Size
+    );
+
+
+//
+// generic.c
+//
+
+static inline ext3_fsblk_t ext3_blocks_count(struct ext3_super_block *es)
+{
+    return ((ext3_fsblk_t)le32_to_cpu(es->s_blocks_count_hi) << 32) |
+           le32_to_cpu(es->s_blocks_count);
+}
+
+static inline ext3_fsblk_t ext3_r_blocks_count(struct ext3_super_block *es)
+{
+    return ((ext3_fsblk_t)le32_to_cpu(es->s_r_blocks_count_hi) << 32) |
+           le32_to_cpu(es->s_r_blocks_count);
+}
+
+static inline ext3_fsblk_t ext3_free_blocks_count(struct ext3_super_block *es)
+{
+    return ((ext3_fsblk_t)le32_to_cpu(es->s_free_blocks_count_hi) << 32) |
+           le32_to_cpu(es->s_free_blocks_count);
+}
+
+static inline void ext3_blocks_count_set(struct ext3_super_block *es,
+        ext3_fsblk_t blk)
+{
+    es->s_blocks_count = cpu_to_le32((u32)blk);
+    es->s_blocks_count_hi = cpu_to_le32(blk >> 32);
+}
+
+static inline void ext3_free_blocks_count_set(struct ext3_super_block *es,
+        ext3_fsblk_t blk)
+{
+    es->s_free_blocks_count = cpu_to_le32((u32)blk);
+    es->s_free_blocks_count_hi = cpu_to_le32(blk >> 32);
+}
+
+static inline void ext3_r_blocks_count_set(struct ext3_super_block *es,
+        ext3_fsblk_t blk)
+{
+    es->s_r_blocks_count = cpu_to_le32((u32)blk);
+    es->s_r_blocks_count_hi = cpu_to_le32(blk >> 32);
+}
+
+blkcnt_t ext3_inode_blocks(struct ext3_inode *raw_inode,
+                           struct inode *inode);
+
+int ext3_inode_blocks_set(struct ext3_inode *raw_inode,
+                          struct inode * inode);
+ext4_fsblk_t ext4_block_bitmap(struct super_block *sb,
+                               struct ext4_group_desc *bg);
+
+ext4_fsblk_t ext4_inode_bitmap(struct super_block *sb,
+                               struct ext4_group_desc *bg);
+ext4_fsblk_t ext4_inode_table(struct super_block *sb,
+                              struct ext4_group_desc *bg);
+__u32 ext4_free_blks_count(struct super_block *sb,
+                           struct ext4_group_desc *bg);
+__u32 ext4_free_inodes_count(struct super_block *sb,
+                             struct ext4_group_desc *bg);
+__u32 ext4_used_dirs_count(struct super_block *sb,
+                           struct ext4_group_desc *bg);
+__u32 ext4_itable_unused_count(struct super_block *sb,
+                               struct ext4_group_desc *bg);
+void ext4_block_bitmap_set(struct super_block *sb,
+                           struct ext4_group_desc *bg, ext4_fsblk_t blk);
+void ext4_inode_bitmap_set(struct super_block *sb,
+                           struct ext4_group_desc *bg, ext4_fsblk_t blk);
+void ext4_inode_table_set(struct super_block *sb,
+                          struct ext4_group_desc *bg, ext4_fsblk_t blk);
+void ext4_free_blks_set(struct super_block *sb,
+                        struct ext4_group_desc *bg, __u32 count);
+void ext4_free_inodes_set(struct super_block *sb,
+                          struct ext4_group_desc *bg, __u32 count);
+void ext4_used_dirs_set(struct super_block *sb,
+                        struct ext4_group_desc *bg, __u32 count);
+void ext4_itable_unused_set(struct super_block *sb,
+                            struct ext4_group_desc *bg, __u32 count);
+
+int ext3_bg_has_super(struct super_block *sb, ext3_group_t group);
+unsigned long ext4_bg_num_gdb(struct super_block *sb, ext4_group_t group);
+unsigned ext4_init_inode_bitmap(struct super_block *sb, struct buffer_head *bh,
+                                ext4_group_t block_group,
+                                struct ext4_group_desc *gdp);
+unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh,
+                                ext4_group_t block_group, struct ext4_group_desc *gdp);
+struct ext4_group_desc * ext4_get_group_desc(struct super_block *sb,
+                    ext4_group_t block_group, struct buffer_head **bh);
+ext4_fsblk_t ext4_count_free_blocks(struct super_block *sb);
+unsigned long ext4_count_free_inodes(struct super_block *sb);
+int ext4_check_descriptors(struct super_block *sb);
+
+NTSTATUS
+Ext2LoadSuper(
+    IN PEXT2_VCB      Vcb,
+    IN BOOLEAN        bVerify,
+    OUT PEXT2_SUPER_BLOCK * Sb
+);
+
+
+BOOLEAN
+Ext2SaveSuper(
+    IN PEXT2_IRP_CONTEXT    IrpContext,
+    IN PEXT2_VCB            Vcb
+);
+
+BOOLEAN
+Ext2RefreshSuper(
+    IN PEXT2_IRP_CONTEXT    IrpContext,
+    IN PEXT2_VCB            Vcb
+);
+
+BOOLEAN
+Ext2LoadGroup(IN PEXT2_VCB Vcb);
+
+VOID
+Ext2PutGroup(IN PEXT2_VCB Vcb);
+
+BOOLEAN
+Ext2SaveGroup(
+    IN PEXT2_IRP_CONTEXT    IrpContext,
+    IN PEXT2_VCB            Vcb,
+    IN ULONG                Group
+);
+
+BOOLEAN
+Ext2RefreshGroup(
+    IN PEXT2_IRP_CONTEXT    IrpContext,
+    IN PEXT2_VCB            Vcb
+);
+
+BOOLEAN
+Ext2GetInodeLba (
+    IN PEXT2_VCB Vcb,
+    IN ULONG inode,
+    OUT PLONGLONG offset
+);
+
+BOOLEAN
+Ext2LoadInode (
+    IN PEXT2_VCB Vcb,
+    IN struct inode *Inode
+);
+
+BOOLEAN
+Ext2ClearInode (
+    IN PEXT2_IRP_CONTEXT    IrpContext,
+    IN PEXT2_VCB Vcb,
+    IN ULONG inode
+);
+
+BOOLEAN
+Ext2SaveInode (
+    IN PEXT2_IRP_CONTEXT IrpContext,
+    IN PEXT2_VCB Vcb,
+    IN struct inode *Inode
+);
+
+BOOLEAN
+Ext2LoadBlock (
+    IN PEXT2_VCB Vcb,
+    IN ULONG     dwBlk,
+    IN PVOID     Buffer
+);
+
+BOOLEAN
+Ext2SaveBlock (
+    IN PEXT2_IRP_CONTEXT    IrpContext,
+    IN PEXT2_VCB            Vcb,
+    IN ULONG                dwBlk,
+    IN PVOID                Buf
+);
+
+BOOLEAN
+Ext2ZeroBuffer(
+    IN PEXT2_IRP_CONTEXT    IrpContext,
+    IN PEXT2_VCB            Vcb,
+    IN LONGLONG             Offset,
+    IN ULONG                Size
+);
+
+BOOLEAN
+Ext2SaveBuffer(
+    IN PEXT2_IRP_CONTEXT    IrpContext,
+    IN PEXT2_VCB            Vcb,
+    IN LONGLONG             Offset,
+    IN ULONG                Size,
+    IN PVOID                Buf
+);
+
+NTSTATUS
+Ext2GetBlock(
+    IN PEXT2_IRP_CONTEXT    IrpContext,
+    IN PEXT2_VCB            Vcb,
+    IN PEXT2_MCB            Mcb,
+    IN ULONG                Base,
+    IN ULONG                Layer,
+    IN ULONG                Start,
+    IN ULONG                SizeArray,
+    IN PULONG               BlockArray,
+    IN BOOLEAN              bAlloc,
+    IN OUT PULONG           Hint,
+    OUT PULONG              Block,
+    OUT PULONG              Number
+);
+
+NTSTATUS
+Ext2BlockMap(
+    IN PEXT2_IRP_CONTEXT    IrpContext,
+    IN PEXT2_VCB            Vcb,
+    IN PEXT2_MCB            Mcb,
+    IN ULONG                Index,
+    IN BOOLEAN              bAlloc,
+    OUT PULONG              pBlock,
+    OUT PULONG              Number
+);
+
+VOID
+Ext2UpdateVcbStat(
+    IN PEXT2_IRP_CONTEXT    IrpContext,
+    IN PEXT2_VCB            Vcb
+);
+
+NTSTATUS
+Ext2NewBlock(
+    IN PEXT2_IRP_CONTEXT    IrpContext,
+    IN PEXT2_VCB            Vcb,
+    IN ULONG                GroupHint,
+    IN ULONG                BlockHint,
+    OUT PULONG              Block,
+    IN OUT PULONG           Number
+);
+
+NTSTATUS
+Ext2FreeBlock(
+    IN PEXT2_IRP_CONTEXT    IrpContext,
+    IN PEXT2_VCB            Vcb,
+    IN ULONG                Block,
+    IN ULONG                Number
+);
+
+
+NTSTATUS
+Ext2NewInode(
+    IN PEXT2_IRP_CONTEXT    IrpContext,
+    IN PEXT2_VCB            Vcb,
+    IN ULONG                GroupHint,
+    IN ULONG                Type,
+    OUT PULONG              Inode
+);
+
+NTSTATUS
+Ext2FreeInode(
+    IN PEXT2_IRP_CONTEXT    IrpContext,
+    IN PEXT2_VCB            Vcb,
+    IN ULONG                Inode,
+    IN ULONG                Type
+);
+
+NTSTATUS
+Ext2AddEntry (
+    IN PEXT2_IRP_CONTEXT   IrpContext,
+    IN PEXT2_VCB           Vcb,
+    IN PEXT2_FCB           Dcb,
+    IN struct inode       *Inode,
+    IN PUNICODE_STRING     FileName,
+    OUT struct dentry    **dentry
+);
+
+NTSTATUS
+Ext2RemoveEntry (
+    IN PEXT2_IRP_CONTEXT    IrpContext,
+    IN PEXT2_VCB            Vcb,
+    IN PEXT2_FCB            Dcb,
+    IN PEXT2_MCB            Mcb
+);
+
+NTSTATUS
+Ext2SetParentEntry (
+    IN PEXT2_IRP_CONTEXT   IrpContext,
+    IN PEXT2_VCB           Vcb,
+    IN PEXT2_FCB           Dcb,
+    IN ULONG               OldParent,
+    IN ULONG               NewParent );
+
+
+NTSTATUS
+Ext2TruncateBlock(
+    IN PEXT2_IRP_CONTEXT IrpContext,
+    IN PEXT2_VCB         Vcb,
+    IN PEXT2_MCB         Mcb,
+    IN ULONG             Base,
+    IN ULONG             Start,
+    IN ULONG             Layer,
+    IN ULONG             SizeArray,
+    IN PULONG            BlockArray,
+    IN PULONG            Extra
+);
+
+struct ext3_dir_entry_2 *ext3_next_entry(struct ext3_dir_entry_2 *p);
+
+int ext3_check_dir_entry (const char * function, struct inode * dir,
+                          struct ext3_dir_entry_2 * de,
+                          struct buffer_head * bh,
+                          unsigned long offset);
+
+loff_t ext3_max_size(int blkbits, int has_huge_files);
+loff_t ext3_max_bitmap_size(int bits, int has_huge_files);
+
+
+__le16 ext4_group_desc_csum(struct ext3_sb_info *sbi, __u32 block_group,
+                            struct ext4_group_desc *gdp);
+int ext4_group_desc_csum_verify(struct ext3_sb_info *sbi, __u32 block_group,
+                                struct ext4_group_desc *gdp);
+
+ext3_fsblk_t descriptor_loc(struct super_block *sb,
+                            ext3_fsblk_t logical_sb_block, unsigned int nr);
+struct ext4_group_desc * ext4_get_group_desc(struct super_block *sb,
+                    ext4_group_t block_group, struct buffer_head **bh);
+int ext4_check_descriptors(struct super_block *sb);
+
+//
+// Fastio.c
+//
+
+FAST_IO_POSSIBLE
+Ext2IsFastIoPossible(
+    IN PEXT2_FCB Fcb
+);
+
+BOOLEAN NTAPI
+Ext2FastIoCheckIfPossible (
+    IN PFILE_OBJECT         FileObject,
+    IN PLARGE_INTEGER       FileOffset,
+    IN ULONG                Length,
+    IN BOOLEAN              Wait,
+    IN ULONG                LockKey,
+    IN BOOLEAN              CheckForReadOperation,
+    OUT PIO_STATUS_BLOCK    IoStatus,
+    IN PDEVICE_OBJECT       DeviceObject
+);
+
+
+BOOLEAN NTAPI
+Ext2FastIoRead (IN PFILE_OBJECT FileObject,
+                IN PLARGE_INTEGER       FileOffset,
+                IN ULONG                Length,
+                IN BOOLEAN              Wait,
+                IN ULONG                LockKey,
+                OUT PVOID               Buffer,
+                OUT PIO_STATUS_BLOCK    IoStatus,
+                IN PDEVICE_OBJECT       DeviceObject);
+
+BOOLEAN NTAPI
+Ext2FastIoWrite (
+    IN PFILE_OBJECT         FileObject,
+    IN PLARGE_INTEGER       FileOffset,
+    IN ULONG                Length,
+    IN BOOLEAN              Wait,
+    IN ULONG                LockKey,
+    OUT PVOID               Buffer,
+    OUT PIO_STATUS_BLOCK    IoStatus,
+    IN PDEVICE_OBJECT       DeviceObject);
+
+BOOLEAN NTAPI
+Ext2FastIoQueryBasicInfo (
+    IN PFILE_OBJECT             FileObject,
+    IN BOOLEAN                  Wait,
+    OUT PFILE_BASIC_INFORMATION Buffer,
+    OUT PIO_STATUS_BLOCK        IoStatus,
+    IN PDEVICE_OBJECT           DeviceObject);
+
+BOOLEAN NTAPI
+Ext2FastIoQueryStandardInfo (
+    IN PFILE_OBJECT                 FileObject,
+    IN BOOLEAN                      Wait,
+    OUT PFILE_STANDARD_INFORMATION  Buffer,
+    OUT PIO_STATUS_BLOCK            IoStatus,
+    IN PDEVICE_OBJECT               DeviceObject);
+
+BOOLEAN NTAPI
+Ext2FastIoLock (
+    IN PFILE_OBJECT         FileObject,
+    IN PLARGE_INTEGER       FileOffset,
+    IN PLARGE_INTEGER       Length,
+    IN PEPROCESS            Process,
+    IN ULONG                Key,
+    IN BOOLEAN              FailImmediately,
+    IN BOOLEAN              ExclusiveLock,
+    OUT PIO_STATUS_BLOCK    IoStatus,
+    IN PDEVICE_OBJECT       DeviceObject
+);
+
+BOOLEAN NTAPI
+Ext2FastIoUnlockSingle (
+    IN PFILE_OBJECT         FileObject,
+    IN PLARGE_INTEGER       FileOffset,
+    IN PLARGE_INTEGER       Length,
+    IN PEPROCESS            Process,
+    IN ULONG                Key,
+    OUT PIO_STATUS_BLOCK    IoStatus,
+    IN PDEVICE_OBJECT       DeviceObject
+);
+
+BOOLEAN NTAPI
+Ext2FastIoUnlockAll (
+    IN PFILE_OBJECT         FileObject,
+    IN PEPROCESS            Process,
+    OUT PIO_STATUS_BLOCK    IoStatus,
+    IN PDEVICE_OBJECT       DeviceObject
+);
+
+BOOLEAN NTAPI
+Ext2FastIoUnlockAllByKey (
+    IN PFILE_OBJECT         FileObject,
+    IN PEPROCESS            Process,
+    IN ULONG                Key,
+    OUT PIO_STATUS_BLOCK    IoStatus,
+    IN PDEVICE_OBJECT       DeviceObject
+);
+
+
+BOOLEAN NTAPI
+Ext2FastIoQueryNetworkOpenInfo (
+    IN PFILE_OBJECT                     FileObject,
+    IN BOOLEAN                          Wait,
+    OUT PFILE_NETWORK_OPEN_INFORMATION  Buffer,
+    OUT PIO_STATUS_BLOCK                IoStatus,
+    IN PDEVICE_OBJECT                   DeviceObject );
+
+BOOLEAN NTAPI
+Ext2FastIoQueryNetworkOpenInfo (
+    IN PFILE_OBJECT                     FileObject,
+    IN BOOLEAN                          Wait,
+    OUT PFILE_NETWORK_OPEN_INFORMATION  Buffer,
+    OUT PIO_STATUS_BLOCK                IoStatus,
+    IN PDEVICE_OBJECT                   DeviceObject);
+
+
+//
+// FileInfo.c
+//
+
+
+NTSTATUS
+Ext2QueryFileInformation (IN PEXT2_IRP_CONTEXT IrpContext);
+
+NTSTATUS
+Ext2SetFileInformation (IN PEXT2_IRP_CONTEXT IrpContext);
+
+ULONG
+Ext2TotalBlocks(
+    PEXT2_VCB         Vcb,
+    PLARGE_INTEGER    Size,
+    PULONG            pMeta
+);
+
+NTSTATUS
+Ext2ExpandFile(
+    PEXT2_IRP_CONTEXT IrpContext,
+    PEXT2_VCB         Vcb,
+    PEXT2_MCB         Mcb,
+    PLARGE_INTEGER    Size
+);
+
+NTSTATUS
+Ext2TruncateFile (
+    PEXT2_IRP_CONTEXT IrpContext,
+    PEXT2_VCB Vcb,
+    PEXT2_MCB Mcb,
+    PLARGE_INTEGER AllocationSize );
+
+NTSTATUS
+Ext2IsFileRemovable(
+    IN PEXT2_IRP_CONTEXT    IrpContext,
+    IN PEXT2_VCB            Vcb,
+    IN PEXT2_FCB            Fcb,
+    IN PEXT2_CCB            Ccb
+);
+
+NTSTATUS
+Ext2SetDispositionInfo(
+    PEXT2_IRP_CONTEXT IrpContext,
+    PEXT2_VCB Vcb,
+    PEXT2_FCB Fcb,
+    PEXT2_CCB Ccb,
+    BOOLEAN bDelete
+);
+
+NTSTATUS
+Ext2SetRenameInfo(
+    PEXT2_IRP_CONTEXT IrpContext,
+    PEXT2_VCB Vcb,
+    PEXT2_FCB Fcb,
+    PEXT2_CCB Ccb
+);
+
+ULONG
+Ext2InodeType(PEXT2_MCB Mcb);
+
+NTSTATUS
+Ext2DeleteFile(
+    PEXT2_IRP_CONTEXT IrpContext,
+    PEXT2_VCB Vcb,
+    PEXT2_FCB Fcb,
+    PEXT2_MCB Mcb
+);
+
+
+//
+// Flush.c
+//
+
+NTSTATUS
+Ext2FlushFiles(
+    IN PEXT2_IRP_CONTEXT    IrpContext,
+    IN PEXT2_VCB            Vcb,
+    IN BOOLEAN              bShutDown
+);
+
+NTSTATUS
+Ext2FlushVolume (
+    IN PEXT2_IRP_CONTEXT    IrpContext,
+    IN PEXT2_VCB            Vcb,
+    IN BOOLEAN              bShutDown
+);
+
+NTSTATUS
+Ext2FlushFile (
+    IN PEXT2_IRP_CONTEXT    IrpContext,
+    IN PEXT2_FCB            Fcb,
+    IN PEXT2_CCB            Ccb
+);
+
+NTSTATUS
+Ext2Flush (IN PEXT2_IRP_CONTEXT IrpContext);
+
+
+//
+// Fsctl.c
+//
+
+//
+// MountPoint process workitem
+//
+
+VOID
+Ext2SetVpbFlag (IN PVPB     Vpb,
+                IN USHORT   Flag );
+
+VOID
+Ext2ClearVpbFlag (IN PVPB     Vpb,
+                  IN USHORT   Flag );
+
+BOOLEAN
+Ext2CheckDismount (
+    IN PEXT2_IRP_CONTEXT IrpContext,
+    IN PEXT2_VCB         Vcb,
+    IN BOOLEAN           bForce   );
+
+NTSTATUS
+Ext2PurgeVolume (IN PEXT2_VCB Vcb,
+                 IN BOOLEAN  FlushBeforePurge);
+
+NTSTATUS
+Ext2PurgeFile (IN PEXT2_FCB Fcb,
+               IN BOOLEAN  FlushBeforePurge);
+
+BOOLEAN
+Ext2IsHandleCountZero(IN PEXT2_VCB Vcb);
+
+NTSTATUS
+Ext2LockVcb (IN PEXT2_VCB    Vcb,
+             IN PFILE_OBJECT FileObject);
+
+NTSTATUS
+Ext2LockVolume (IN PEXT2_IRP_CONTEXT IrpContext);
+
+NTSTATUS
+Ext2UnlockVcb (IN PEXT2_VCB    Vcb,
+               IN PFILE_OBJECT FileObject);
+
+NTSTATUS
+Ext2UnlockVolume (IN PEXT2_IRP_CONTEXT IrpContext);
+
+NTSTATUS
+Ext2AllowExtendedDasdIo(IN PEXT2_IRP_CONTEXT IrpContext);
+
+NTSTATUS
+Ext2OplockRequest (IN PEXT2_IRP_CONTEXT IrpContext);
+
+NTSTATUS
+Ext2QueryExtentMappings(
+    IN PEXT2_IRP_CONTEXT   IrpContext,
+    IN PEXT2_VCB           Vcb,
+    IN PEXT2_FCB           Fcb,
+    IN PLARGE_INTEGER      RequestVbn,
+    OUT PLARGE_INTEGER *   pMappedRuns
+);
+
+NTSTATUS
+Ext2QueryRetrievalPointers(IN PEXT2_IRP_CONTEXT IrpContext);
+
+NTSTATUS
+Ext2GetRetrievalPointers(IN PEXT2_IRP_CONTEXT IrpContext);
+
+NTSTATUS
+Ext2GetRetrievalPointerBase(IN PEXT2_IRP_CONTEXT IrpContext);
+
+NTSTATUS
+Ext2UserFsRequest (IN PEXT2_IRP_CONTEXT IrpContext);
+
+BOOLEAN
+Ext2IsMediaWriteProtected (
+    IN PEXT2_IRP_CONTEXT   IrpContext,
+    IN PDEVICE_OBJECT TargetDevice
+);
+
+NTSTATUS
+Ext2MountVolume (IN PEXT2_IRP_CONTEXT IrpContext);
+
+VOID
+Ext2VerifyVcb (IN PEXT2_IRP_CONTEXT IrpContext,
+               IN PEXT2_VCB         Vcb );
+NTSTATUS
+Ext2VerifyVolume (IN PEXT2_IRP_CONTEXT IrpContext);
+
+NTSTATUS
+Ext2IsVolumeMounted (IN PEXT2_IRP_CONTEXT IrpContext);
+
+NTSTATUS
+Ext2DismountVolume (IN PEXT2_IRP_CONTEXT IrpContext);
+
+NTSTATUS
+Ext2FileSystemControl (IN PEXT2_IRP_CONTEXT IrpContext);
+
+//
+// HTree.c
+//
+
+struct buffer_head *ext3_append(struct ext2_icb *icb, struct inode *inode,
+                                            ext3_lblk_t *block, int *err);
+
+void ext3_set_de_type(struct super_block *sb,
+                      struct ext3_dir_entry_2 *de,
+                      umode_t mode);
+
+__u32 ext3_current_time(struct inode *in);
+void ext3_warning (struct super_block * sb, const char * function,
+                   char * fmt, ...);
+#define ext3_error ext3_warning
+#define ext4_error ext3_error
+
+void ext3_update_dx_flag(struct inode *inode);
+int ext3_mark_inode_dirty(struct ext2_icb *icb, struct inode *in);
+
+void ext3_inc_count(struct inode *inode);
+void ext3_dec_count(struct inode *inode);
+
+struct buffer_head *
+            ext3_find_entry (struct ext2_icb *icb, struct dentry *dentry,
+                             struct ext3_dir_entry_2 ** res_dir);
+struct buffer_head *
+            ext3_dx_find_entry(struct ext2_icb *, struct dentry *dentry,
+                               struct ext3_dir_entry_2 **res_dir, int *err);
+
+typedef int (*filldir_t)(void *, const char *, int, unsigned long, __u32, unsigned);
+int ext3_dx_readdir(struct file *filp, filldir_t filldir, void * context);
+
+struct buffer_head *ext3_bread(struct ext2_icb *icb, struct inode *inode,
+                                           unsigned long block, int *err);
+int add_dirent_to_buf(struct ext2_icb *icb, struct dentry *dentry,
+                      struct inode *inode, struct ext3_dir_entry_2 *de,
+                      struct buffer_head *bh);
+
+#if !defined(__REACTOS__) || defined(_MSC_VER)
+struct ext3_dir_entry_2 *
+            do_split(struct ext2_icb *icb, struct inode *dir,
+                     struct buffer_head **bh,struct dx_frame *frame,
+                     struct dx_hash_info *hinfo, int *error);
+#endif
+
+int ext3_add_entry(struct ext2_icb *icb, struct dentry *dentry, struct inode *inode);
+
+int ext3_delete_entry(struct ext2_icb *icb, struct inode *dir,
+                      struct ext3_dir_entry_2 *de_del,
+                      struct buffer_head *bh);
+
+int ext3_is_dir_empty(struct ext2_icb *icb, struct inode *inode);
+
+//
+// Init.c
+//
+
+BOOLEAN
+Ext2QueryGlobalParameters (IN PUNICODE_STRING  RegistryPath);
+
+VOID NTAPI
+DriverUnload (IN PDRIVER_OBJECT DriverObject);
+
+//
+// Indirect.c
+//
+
+NTSTATUS
+Ext2MapIndirect(
+    IN PEXT2_IRP_CONTEXT    IrpContext,
+    IN PEXT2_VCB            Vcb,
+    IN PEXT2_MCB            Mcb,
+    IN ULONG                Index,
+    IN BOOLEAN              bAlloc,
+    OUT PULONG              pBlock,
+    OUT PULONG              Number
+);
+
+NTSTATUS
+Ext2ExpandIndirect(
+    PEXT2_IRP_CONTEXT IrpContext,
+    PEXT2_VCB         Vcb,
+    PEXT2_MCB         Mcb,
+    ULONG             Start,
+    ULONG             End,
+    PLARGE_INTEGER    Size
+);
+
+NTSTATUS
+Ext2TruncateIndirect(
+    PEXT2_IRP_CONTEXT IrpContext,
+    PEXT2_VCB         Vcb,
+    PEXT2_MCB         Mcb,
+    PLARGE_INTEGER    Size
+);
+
+
+//
+// linux.c: linux lib implemenation
+//
+
+int
+ext2_init_linux();
+
+void
+ext2_destroy_linux();
+
+
+//
+// Lock.c
+//
+
+NTSTATUS
+Ext2LockControl (IN PEXT2_IRP_CONTEXT IrpContext);
+
+
+//
+// Memory.c
+//
+
+PEXT2_IRP_CONTEXT
+Ext2AllocateIrpContext (IN PDEVICE_OBJECT   DeviceObject,
+                        IN PIRP             Irp );
+
+VOID
+Ext2FreeIrpContext (IN PEXT2_IRP_CONTEXT IrpContext);
+
+
+PEXT2_FCB
+Ext2AllocateFcb (
+    IN PEXT2_VCB   Vcb,
+    IN PEXT2_MCB   Mcb
+);
+
+VOID
+Ext2FreeFcb (IN PEXT2_FCB Fcb);
+
+VOID
+Ext2InsertFcb(PEXT2_VCB Vcb, PEXT2_FCB Fcb);
+
+VOID
+Ext2RemoveFcb(PEXT2_VCB Vcb, PEXT2_FCB Fcb);
+
+PEXT2_CCB
+Ext2AllocateCcb (PEXT2_MCB  SymLink);
+
+VOID
+Ext2FreeMcb (
+    IN PEXT2_VCB        Vcb,
+    IN PEXT2_MCB        Mcb
+);
+
+VOID
+Ext2FreeCcb (IN PEXT2_VCB Vcb, IN PEXT2_CCB Ccb);
+
+PEXT2_INODE
+Ext2AllocateInode (PEXT2_VCB  Vcb);
+
+VOID
+Ext2DestroyInode (IN PEXT2_VCB Vcb, IN PEXT2_INODE inode);
+
+struct dentry * Ext2AllocateEntry();
+VOID Ext2FreeEntry (IN struct dentry *de);
+struct dentry *Ext2BuildEntry(PEXT2_VCB Vcb, PEXT2_MCB Dcb, PUNICODE_STRING FileName);
+
+PEXT2_EXTENT
+Ext2AllocateExtent();
+
+VOID
+Ext2FreeExtent (IN PEXT2_EXTENT Extent);
+
+ULONG
+Ext2CountExtents(IN PEXT2_EXTENT Chain);
+
+VOID
+Ext2JointExtents(
+    IN PEXT2_EXTENT Chain,
+    IN PEXT2_EXTENT Extent
+);
+
+VOID
+Ext2DestroyExtentChain(IN PEXT2_EXTENT Chain);
+
+NTSTATUS
+Ext2BuildExtents(
+    IN PEXT2_IRP_CONTEXT    IrpContext,
+    IN PEXT2_VCB            Vcb,
+    IN PEXT2_MCB            Mcb,
+    IN ULONGLONG            Offset,
+    IN ULONG                Size,
+    IN BOOLEAN              bAlloc,
+    OUT PEXT2_EXTENT *      Chain
+);
+
+BOOLEAN
+Ext2ListExtents(PLARGE_MCB  Extents);
+
+VOID
+Ext2CheckExtent(
+    PLARGE_MCB  Zone,
+    LONGLONG    Vbn,
+    LONGLONG    Lbn,
+    LONGLONG    Length,
+    BOOLEAN     bAdded
+);
+
+VOID
+Ext2ClearAllExtents(PLARGE_MCB  Zone);
+
+BOOLEAN
+Ext2AddVcbExtent (
+    IN PEXT2_VCB Vcb,
+    IN LONGLONG  Vbn,
+    IN LONGLONG  Length
+);
+
+BOOLEAN
+Ext2RemoveVcbExtent (
+    IN PEXT2_VCB Vcb,
+    IN LONGLONG  Vbn,
+    IN LONGLONG  Length
+);
+
+BOOLEAN
+Ext2LookupVcbExtent (
+    IN PEXT2_VCB    Vcb,
+    IN LONGLONG     Vbn,
+    OUT PLONGLONG   Lbn,
+    OUT PLONGLONG   Length
+);
+
+BOOLEAN
+Ext2AddMcbExtent (
+    IN PEXT2_VCB Vcb,
+    IN PEXT2_MCB Mcb,
+    IN LONGLONG  Vbn,
+    IN LONGLONG  Lbn,
+    IN LONGLONG  Length
+);
+
+BOOLEAN
+Ext2RemoveMcbExtent (
+    IN PEXT2_VCB Vcb,
+    IN PEXT2_MCB Mcb,
+    IN LONGLONG  Vbn,
+    IN LONGLONG  Length
+);
+
+BOOLEAN
+Ext2LookupMcbExtent (
+    IN PEXT2_VCB    Vcb,
+    IN PEXT2_MCB    Mcb,
+    IN LONGLONG     Vbn,
+    OUT PLONGLONG   Lbn,
+    OUT PLONGLONG   Length
+);
+
+BOOLEAN
+Ext2AddMcbMetaExts (
+    IN PEXT2_VCB Vcb,
+    IN PEXT2_MCB Mcb,
+    IN ULONG     Block,
+    IN ULONG     Length
+);
+
+BOOLEAN
+Ext2RemoveMcbMetaExts (
+    IN PEXT2_VCB Vcb,
+    IN PEXT2_MCB Mcb,
+    IN ULONG     Block,
+    IN ULONG     Length
+);
+
+BOOLEAN
+Ext2AddBlockExtent(
+    IN PEXT2_VCB    Vcb,
+    IN PEXT2_MCB    Mcb,
+    IN ULONG        Start,
+    IN ULONG        Block,
+    IN ULONG        Number
+);
+
+BOOLEAN
+Ext2LookupBlockExtent(
+    IN PEXT2_VCB    Vcb,
+    IN PEXT2_MCB    Mcb,
+    IN ULONG        Start,
+    IN PULONG       Block,
+    IN PULONG       Mapped
+);
+
+BOOLEAN
+Ext2RemoveBlockExtent(
+    IN PEXT2_VCB    Vcb,
+    IN PEXT2_MCB    Mcb,
+    IN ULONG        Start,
+    IN ULONG        Number
+);
+
+NTSTATUS
+Ext2InitializeZone(
+    IN PEXT2_IRP_CONTEXT    IrpContext,
+    IN PEXT2_VCB            Vcb,
+    IN PEXT2_MCB            Mcb
+);
+
+BOOLEAN
+Ext2BuildName(
+    IN OUT PUNICODE_STRING  Target,
+    IN PUNICODE_STRING      File,
+    IN PUNICODE_STRING      Parent
+);
+
+
+PEXT2_MCB
+Ext2AllocateMcb (
+    IN PEXT2_VCB        Vcb,
+    IN PUNICODE_STRING  FileName,
+    IN PUNICODE_STRING  Parent,
+    IN ULONG            FileAttr
+);
+
+PEXT2_MCB
+Ext2SearchMcb(
+    PEXT2_VCB           Vcb,
+    PEXT2_MCB           Parent,
+    PUNICODE_STRING     FileName
+);
+
+PEXT2_MCB
+Ext2SearchMcbWithoutLock(
+    PEXT2_MCB           Parent,
+    PUNICODE_STRING     FileName
+);
+
+VOID
+Ext2InsertMcb(
+    PEXT2_VCB Vcb,
+    PEXT2_MCB Parent,
+    PEXT2_MCB Child
+);
+
+BOOLEAN
+Ext2RemoveMcb(
+    PEXT2_VCB Vcb,
+    PEXT2_MCB Mcb
+);
+
+VOID
+Ext2CleanupAllMcbs(
+    PEXT2_VCB Vcb
+);
+
+BOOLEAN
+Ext2CheckSetBlock(
+    PEXT2_IRP_CONTEXT IrpContext,
+    PEXT2_VCB Vcb, LONGLONG Block
+);
+
+BOOLEAN
+Ext2CheckBitmapConsistency(
+    PEXT2_IRP_CONTEXT IrpContext,
+    PEXT2_VCB Vcb
+);
+
+VOID
+Ext2InsertVcb(PEXT2_VCB Vcb);
+
+VOID
+Ext2RemoveVcb(PEXT2_VCB Vcb);
+
+NTSTATUS
+Ext2InitializeLabel(
+    IN PEXT2_VCB            Vcb,
+    IN PEXT2_SUPER_BLOCK    Sb
+);
+
+NTSTATUS
+Ext2InitializeVcb(
+    PEXT2_IRP_CONTEXT IrpContext,
+    PEXT2_VCB Vcb,
+    PEXT2_SUPER_BLOCK Ext2Sb,
+    PDEVICE_OBJECT TargetDevice,
+    PDEVICE_OBJECT VolumeDevice,
+    PVPB Vpb                   );
+
+VOID
+Ext2TearDownStream (IN PEXT2_VCB Vcb);
+
+VOID
+Ext2DestroyVcb (IN PEXT2_VCB Vcb);
+
+NTSTATUS
+Ext2CompleteIrpContext (
+    IN PEXT2_IRP_CONTEXT IrpContext,
+    IN NTSTATUS Status );
+
+VOID
+Ext2SyncUninitializeCacheMap (
+    IN PFILE_OBJECT FileObject    );
+
+VOID
+Ext2LinkTailMcb(PEXT2_VCB Vcb, PEXT2_MCB Mcb);
+
+
+VOID
+Ext2LinkHeadMcb(PEXT2_VCB Vcb, PEXT2_MCB Mcb);
+
+VOID
+Ext2UnlinkMcb(PEXT2_VCB Vcb, PEXT2_MCB Mcb);
+
+PEXT2_MCB
+Ext2FirstUnusedMcb(
+    PEXT2_VCB   Vcb,
+    BOOLEAN     Wait,
+    ULONG       Number
+);
+
+VOID NTAPI
+Ext2ReaperThread(
+    PVOID   Context
+);
+
+NTSTATUS
+Ext2StartReaperThread();
+
+//
+// Misc.c
+//
+
+ULONG
+Ext2Log2(ULONG Value);
+
+LARGE_INTEGER
+Ext2NtTime (IN ULONG i_time);
+
+ULONG
+Ext2LinuxTime (IN LARGE_INTEGER SysTime);
+
+ULONG
+Ext2OEMToUnicodeSize(
+    IN PEXT2_VCB        Vcb,
+    IN PANSI_STRING     Oem
+);
+
+NTSTATUS
+Ext2OEMToUnicode(
+    IN PEXT2_VCB           Vcb,
+    IN OUT PUNICODE_STRING Oem,
+    IN POEM_STRING         Unicode
+);
+
+ULONG
+Ext2UnicodeToOEMSize(
+    IN PEXT2_VCB        Vcb,
+    IN PUNICODE_STRING  Unicode
+);
+
+NTSTATUS
+Ext2UnicodeToOEM (
+    IN PEXT2_VCB        Vcb,
+    IN OUT POEM_STRING  Oem,
+    IN PUNICODE_STRING  Unicode
+);
+
+VOID
+Ext2Sleep(ULONG ms);
+
+int Ext2LinuxError (NTSTATUS Status);
+NTSTATUS Ext2WinntError(int rc);
+
+BOOLEAN Ext2IsDot(PUNICODE_STRING name);
+BOOLEAN Ext2IsDotDot(PUNICODE_STRING name);
+//
+// nls/nls_rtl.c
+//
+
+int
+Ext2LoadAllNls();
+
+VOID
+Ext2UnloadAllNls();
+
+//
+// Pnp.c
+//
+
+NTSTATUS
+Ext2Pnp(IN PEXT2_IRP_CONTEXT IrpContext);
+
+NTSTATUS
+Ext2PnpQueryRemove(
+    PEXT2_IRP_CONTEXT IrpContext,
+    PEXT2_VCB         Vcb      );
+
+NTSTATUS
+Ext2PnpRemove(
+    PEXT2_IRP_CONTEXT IrpContext,
+    PEXT2_VCB         Vcb      );
+
+NTSTATUS
+Ext2PnpCancelRemove(
+    PEXT2_IRP_CONTEXT IrpContext,
+    PEXT2_VCB Vcb              );
+
+NTSTATUS
+Ext2PnpSurpriseRemove(
+    PEXT2_IRP_CONTEXT IrpContext,
+    PEXT2_VCB Vcb              );
+
+
+//
+// Read.c
+//
+
+NTSTATUS
+Ext2ReadInode (
+    IN PEXT2_IRP_CONTEXT    IrpContext,
+    IN PEXT2_VCB            Vcb,
+    IN PEXT2_MCB            Mcb,
+    IN ULONGLONG            Offset,
+    IN PVOID                Buffer,
+    IN ULONG                Size,
+    IN BOOLEAN              bDirectIo,
+    OUT PULONG              dwReturn
+);
+
+NTSTATUS
+Ext2Read (IN PEXT2_IRP_CONTEXT IrpContext);
+
+
+//
+// ext3\recover.c
+//
+
+PEXT2_MCB
+Ext2LoadInternalJournal(
+    PEXT2_VCB         Vcb,
+    ULONG             jNo
+);
+
+INT
+Ext2CheckJournal(
+    PEXT2_VCB          Vcb,
+    PULONG             jNo
+);
+
+INT
+Ext2RecoverJournal(
+    PEXT2_IRP_CONTEXT  IrpContext,
+    PEXT2_VCB          Vcb
+);
+
+//
+// Shutdown.c
+//
+
+
+NTSTATUS
+Ext2ShutDown (IN PEXT2_IRP_CONTEXT IrpContext);
+
+
+//
+// Volinfo.c
+//
+
+NTSTATUS
+Ext2QueryVolumeInformation (IN PEXT2_IRP_CONTEXT IrpContext);
+
+NTSTATUS
+Ext2SetVolumeInformation (IN PEXT2_IRP_CONTEXT IrpContext);
+
+//
+// Write.c
+//
+
+typedef struct _EXT2_RW_CONTEXT {
+    PIRP                MasterIrp;
+    KEVENT              Event;
+    ULONG               Blocks;
+    ULONG               Length;
+    PERESOURCE          Resource;
+    ERESOURCE_THREAD    ThreadId;
+    PFILE_OBJECT        FileObject;
+    ULONG               Flags;
+    BOOLEAN             Wait;
+
+} EXT2_RW_CONTEXT, *PEXT2_RW_CONTEXT;
+
+#define EXT2_RW_CONTEXT_WRITE   1
+
+NTSTATUS
+Ext2WriteInode (
+    IN PEXT2_IRP_CONTEXT    IrpContext,
+    IN PEXT2_VCB            Vcb,
+    IN PEXT2_MCB            Mcb,
+    IN ULONGLONG            Offset,
+    IN PVOID                Buffer,
+    IN ULONG                Size,
+    IN BOOLEAN              bDirectIo,
+    OUT PULONG              dwReturn
+);
+
+VOID
+Ext2StartFloppyFlushDpc (
+    PEXT2_VCB   Vcb,
+    PEXT2_FCB   Fcb,
+    PFILE_OBJECT FileObject );
+
+BOOLEAN
+Ext2ZeroData (
+    IN PEXT2_IRP_CONTEXT IrpContext,
+    IN PEXT2_VCB Vcb,
+    IN PFILE_OBJECT FileObject,
+    IN PLARGE_INTEGER Start,
+    IN PLARGE_INTEGER End );
+
+NTSTATUS
+Ext2Write (IN PEXT2_IRP_CONTEXT IrpContext);
+
+#endif /* _EXT2_HEADER_ */
diff --git a/reactos/drivers/filesystems/ext2_new/inc/linux/Ext2_fs.h b/reactos/drivers/filesystems/ext2_new/inc/linux/Ext2_fs.h
new file mode 100644 (file)
index 0000000..93a114c
--- /dev/null
@@ -0,0 +1,638 @@
+/*
+ *  linux/include/linux/ext2_fs.h
+ *
+ * Copyright (C) 1992, 1993, 1994, 1995
+ * Remy Card (card@masi.ibp.fr)
+ * Laboratoire MASI - Institut Blaise Pascal
+ * Universite Pierre et Marie Curie (Paris VI)
+ *
+ *  from
+ *
+ *  linux/include/linux/minix_fs.h
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ */
+
+#ifndef _LINUX_EXT2_FS_H
+#define _LINUX_EXT2_FS_H
+
+#include <linux/types.h>
+
+/*
+ * The second extended filesystem constants/structures
+ */
+
+/*
+ * Define EXT2FS_DEBUG to produce debug messages
+ */
+#undef EXT2FS_DEBUG
+
+/*
+ * Define EXT2_PREALLOCATE to preallocate data blocks for expanding files
+ */
+#define EXT2_PREALLOCATE
+#define EXT2_DEFAULT_PREALLOC_BLOCKS   8
+
+/*
+ * The second extended file system version
+ */
+#define EXT2FS_DATE            "95/08/09"
+#define EXT2FS_VERSION         "0.5b"
+
+/*
+ * Debug code
+ */
+#ifdef EXT2FS_DEBUG
+#      define ext2_debug(f, a...)      { \
+                                       printk ("EXT2-fs DEBUG (%s, %d): %s:", \
+                                               __FILE__, __LINE__, __FUNCTION__); \
+                                       printk (f, ## a); \
+                                       }
+#else
+//#    define ext2_debug(f, a...)      /**/
+#endif
+
+/*
+ * Special inode numbers
+ */
+#define        EXT2_BAD_INO             1      /* Bad blocks inode */
+#define EXT2_ROOT_INO           2      /* Root inode */
+#define EXT2_ACL_IDX_INO        3      /* ACL inode */
+#define EXT2_ACL_DATA_INO       4      /* ACL inode */
+#define EXT2_BOOT_LOADER_INO    5      /* Boot loader inode */
+#define EXT2_UNDEL_DIR_INO      6      /* Undelete directory inode */
+
+/* First non-reserved inode for old ext2 filesystems */
+#define EXT2_GOOD_OLD_FIRST_INO        11
+
+/*
+ * The second extended file system magic number
+ */
+#define EXT2_SUPER_MAGIC       0xEF53
+
+/*
+ * Maximal count of links to a file
+ */
+#define EXT2_LINK_MAX          32000
+
+/*
+ * Macro-instructions used to manage several block sizes
+ */
+#define EXT2_MIN_BLOCK_SIZE            1024
+#define        EXT2_MAX_BLOCK_SIZE             4096
+#define EXT2_MIN_BLOCK_LOG_SIZE 10
+#ifdef __KERNEL__
+# define EXT2_BLOCK_SIZE(s)            ((s)->s_blocksize)
+#else
+# define EXT2_BLOCK_SIZE(s)            (EXT2_MIN_BLOCK_SIZE << (s)->s_log_block_size)
+#endif
+#define EXT2_ACLE_PER_BLOCK(s)         (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_acl_entry))
+#define        EXT2_ADDR_PER_BLOCK(s)          (EXT2_BLOCK_SIZE(s) / sizeof (__u32))
+#ifdef __KERNEL__
+# define EXT2_BLOCK_SIZE_BITS(s)       ((s)->s_blocksize_bits)
+#else
+# define EXT2_BLOCK_SIZE_BITS(s)       ((s)->s_log_block_size + 10)
+#endif
+#ifdef __KERNEL__
+#define        EXT2_ADDR_PER_BLOCK_BITS(s)     ((s)->u.ext2_sb.s_addr_per_block_bits)
+#define EXT2_INODE_SIZE(s)             ((s)->u.ext2_sb.s_inode_size)
+#define EXT2_FIRST_INO(s)              ((s)->u.ext2_sb.s_first_ino)
+#else
+#define EXT2_INODE_SIZE(s)     (((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \
+                                EXT2_GOOD_OLD_INODE_SIZE : \
+                                (s)->s_inode_size)
+#define EXT2_FIRST_INO(s)      (((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \
+                                EXT2_GOOD_OLD_FIRST_INO : \
+                                (s)->s_first_ino)
+#endif
+
+/*
+ * Macro-instructions used to manage fragments
+ */
+#define EXT2_MIN_FRAG_SIZE             1024
+#define        EXT2_MAX_FRAG_SIZE              4096
+#define EXT2_MIN_FRAG_LOG_SIZE           10
+#ifdef __KERNEL__
+# define EXT2_FRAG_SIZE(s)             ((s)->u.ext2_sb.s_frag_size)
+# define EXT2_FRAGS_PER_BLOCK(s)       ((s)->u.ext2_sb.s_frags_per_block)
+#else
+# define EXT2_FRAG_SIZE(s)             (EXT2_MIN_FRAG_SIZE << (s)->s_log_frag_size)
+# define EXT2_FRAGS_PER_BLOCK(s)       (EXT2_BLOCK_SIZE(s) / EXT2_FRAG_SIZE(s))
+#endif
+
+/*
+ * ACL structures
+ */
+struct ext2_acl_header /* Header of Access Control Lists */
+{
+    __u32      aclh_size;
+    __u32      aclh_file_count;
+    __u32      aclh_acle_count;
+    __u32      aclh_first_acle;
+};
+
+struct ext2_acl_entry  /* Access Control List Entry */
+{
+    __u32      acle_size;
+    __u16      acle_perms;     /* Access permissions */
+    __u16      acle_type;      /* Type of entry */
+    __u16      acle_tag;       /* User or group identity */
+    __u16      acle_pad1;
+    __u32      acle_next;      /* Pointer on next entry for the */
+    /* same inode or on next free entry */
+};
+
+/*
+ * Structure of a blocks group descriptor
+ */
+struct ext2_group_desc
+{
+    __u32      bg_block_bitmap;                /* Blocks bitmap block */
+    __u32      bg_inode_bitmap;                /* Inodes bitmap block */
+    __u32      bg_inode_table;         /* Inodes table block */
+    __u16      bg_free_blocks_count;   /* Free blocks count */
+    __u16      bg_free_inodes_count;   /* Free inodes count */
+    __u16      bg_used_dirs_count;     /* Directories count */
+    __u16      bg_pad;
+    __u32      bg_reserved[3];
+};
+
+/*
+ * Macro-instructions used to manage group descriptors
+ */
+#ifdef __KERNEL__
+# define EXT2_BLOCKS_PER_GROUP(s)      ((s)->u.ext2_sb.s_blocks_per_group)
+# define EXT2_DESC_PER_BLOCK(s)                ((s)->u.ext2_sb.s_desc_per_block)
+# define EXT2_INODES_PER_GROUP(s)      ((s)->u.ext2_sb.s_inodes_per_group)
+# define EXT2_DESC_PER_BLOCK_BITS(s)   ((s)->u.ext2_sb.s_desc_per_block_bits)
+#else
+# define EXT2_BLOCKS_PER_GROUP(s)      ((s)->s_blocks_per_group)
+# define EXT2_DESC_PER_BLOCK(s)                (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_group_desc))
+# define EXT2_INODES_PER_GROUP(s)      ((s)->s_inodes_per_group)
+#endif
+
+/*
+ * Constants relative to the data blocks
+ */
+#define        EXT2_NDIR_BLOCKS                12
+#define        EXT2_IND_BLOCK                  EXT2_NDIR_BLOCKS
+#define        EXT2_DIND_BLOCK                 (EXT2_IND_BLOCK + 1)
+#define        EXT2_TIND_BLOCK                 (EXT2_DIND_BLOCK + 1)
+#define        EXT2_N_BLOCKS                   (EXT2_TIND_BLOCK + 1)
+
+/*
+ * Inode flags
+ */
+#define        EXT2_SECRM_FL                   0x00000001 /* Secure deletion */
+#define        EXT2_UNRM_FL                    0x00000002 /* Undelete */
+#define        EXT2_COMPR_FL                   0x00000004 /* Compress file */
+#define EXT2_SYNC_FL                   0x00000008 /* Synchronous updates */
+#define EXT2_IMMUTABLE_FL              0x00000010 /* Immutable file */
+#define EXT2_APPEND_FL                 0x00000020 /* writes to file may only append */
+#define EXT2_NODUMP_FL                 0x00000040 /* do not dump file */
+#define EXT2_NOATIME_FL                        0x00000080 /* do not update atime */
+/* Reserved for compression usage... */
+#define EXT2_DIRTY_FL                  0x00000100
+#define EXT2_COMPRBLK_FL               0x00000200 /* One or more compressed clusters */
+#define EXT2_NOCOMP_FL                 0x00000400 /* Don't compress */
+#define EXT2_ECOMPR_FL                 0x00000800 /* Compression error */
+/* End compression flags --- maybe not all used */
+#define EXT2_BTREE_FL           0x00001000 /* btree format dir */
+#define EXT2_IMAGIC_FL          0x00002000 /* AFS directory */
+#define EXT2_JOURNAL_DATA_FL    0x00004000 /* file data should be journaled */
+#define EXT2_NOTAIL_FL          0x00008000 /* file tail should not be merged */
+#define EXT2_DIRSYNC_FL         0x00010000 /* dirsync behaviour (directories only) */
+#define EXT2_TOPDIR_FL          0x00020000 /* Top of directory hierarchies*/
+#define EXT2_HUGE_FILE_FL       0x00040000 /* Set to each huge file */
+#define EXT2_EXTENTS_FL         0x00080000 /* Inode uses extents */
+#define EXT2_RESERVED_FL        0x80000000 /* reserved for ext2 lib */
+
+#define EXT2_FL_USER_VISIBLE           0x00001FFF /* User visible flags */
+#define EXT2_FL_USER_MODIFIABLE                0x000000FF /* User modifiable flags */
+
+/*
+ * ioctl commands
+ */
+#define        EXT2_IOC_GETFLAGS               _IOR('f', 1, long)
+#define        EXT2_IOC_SETFLAGS               _IOW('f', 2, long)
+#define        EXT2_IOC_GETVERSION             _IOR('v', 1, long)
+#define        EXT2_IOC_SETVERSION             _IOW('v', 2, long)
+
+/*
+ * Structure of an inode on the disk
+ */
+struct ext2_inode {
+    __u16      i_mode;         /* File mode */
+    __u16      i_uid;          /* Low 16 bits of Owner Uid */
+    __u32      i_size;         /* Size in bytes */
+    __u32      i_atime;        /* Access time */
+    __u32      i_ctime;        /* Creation time */
+    __u32      i_mtime;        /* Modification time */
+    __u32      i_dtime;        /* Deletion Time */
+    __u16      i_gid;          /* Low 16 bits of Group Id */
+    __u16      i_links_count;  /* Links count */
+    __u32      i_blocks;       /* Blocks count */
+    __u32      i_flags;        /* File flags */
+    union {
+        struct {
+            __u32  l_i_reserved1;
+        } linux1;
+        struct {
+            __u32  h_i_translator;
+        } hurd1;
+        struct {
+            __u32  m_i_reserved1;
+        } masix1;
+    } osd1;                            /* OS dependent 1 */
+    __u32      i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
+    __u32      i_generation;   /* File version (for NFS) */
+    __u32      i_file_acl;     /* File ACL */
+    __u32      i_dir_acl;      /* Directory ACL */
+    __u32      i_faddr;        /* Fragment address */
+    union {
+        struct {
+            __u8       l_i_frag;       /* Fragment number */
+            __u8       l_i_fsize;      /* Fragment size */
+            __u16      i_pad1;
+            __u16      l_i_uid_high;   /* these 2 fields    */
+            __u16      l_i_gid_high;   /* were reserved2[0] */
+            __u32      l_i_reserved2;
+        } linux2;
+        struct {
+            __u8       h_i_frag;       /* Fragment number */
+            __u8       h_i_fsize;      /* Fragment size */
+            __u16      h_i_mode_high;
+            __u16      h_i_uid_high;
+            __u16      h_i_gid_high;
+            __u32      h_i_author;
+        } hurd2;
+        struct {
+            __u8       m_i_frag;       /* Fragment number */
+            __u8       m_i_fsize;      /* Fragment size */
+            __u16      m_pad1;
+            __u32      m_i_reserved2[2];
+        } masix2;
+    } osd2;                            /* OS dependent 2 */
+    __le16     i_extra_isize;
+    __le16     i_pad1;
+};
+
+#if defined(__KERNEL__) || defined(__linux__)
+#define i_reserved1    osd1.linux1.l_i_reserved1
+#define i_frag         osd2.linux2.l_i_frag
+#define i_fsize                osd2.linux2.l_i_fsize
+#define i_uid_low      i_uid
+#define i_gid_low      i_gid
+#define i_uid_high     osd2.linux2.l_i_uid_high
+#define i_gid_high     osd2.linux2.l_i_gid_high
+#define i_reserved2    osd2.linux2.l_i_reserved2
+#endif
+
+#ifdef __hurd__
+#define i_translator   osd1.hurd1.h_i_translator
+#define i_frag         osd2.hurd2.h_i_frag;
+#define i_fsize                osd2.hurd2.h_i_fsize;
+#define i_uid_high     osd2.hurd2.h_i_uid_high
+#define i_gid_high     osd2.hurd2.h_i_gid_high
+#define i_author       osd2.hurd2.h_i_author
+#endif
+
+#ifdef __masix__
+#define i_reserved1    osd1.masix1.m_i_reserved1
+#define i_frag         osd2.masix2.m_i_frag
+#define i_fsize                osd2.masix2.m_i_fsize
+#define i_reserved2    osd2.masix2.m_i_reserved2
+#endif
+
+/*
+ * File system states
+ */
+#define        EXT2_VALID_FS                   0x0001  /* Unmounted cleanly */
+#define        EXT2_ERROR_FS                   0x0002  /* Errors detected */
+
+/*
+ * Mount flags
+ */
+#define EXT2_MOUNT_CHECK               0x0001  /* Do mount-time checks */
+#define EXT2_MOUNT_GRPID               0x0004  /* Create files with directory's group */
+#define EXT2_MOUNT_DEBUG               0x0008  /* Some debugging messages */
+#define EXT2_MOUNT_ERRORS_CONT         0x0010  /* Continue on errors */
+#define EXT2_MOUNT_ERRORS_RO           0x0020  /* Remount fs ro on errors */
+#define EXT2_MOUNT_ERRORS_PANIC                0x0040  /* Panic on errors */
+#define EXT2_MOUNT_MINIX_DF            0x0080  /* Mimics the Minix statfs */
+#define EXT2_MOUNT_NO_UID32            0x0200  /* Disable 32-bit UIDs */
+
+#define clear_opt(o, opt)              o &= ~EXT2_MOUNT_##opt
+#define set_opt(o, opt)                        o |= EXT2_MOUNT_##opt
+#define test_opt(sb, opt)              ((sb)->u.ext2_sb.s_mount_opt & \
+                                        EXT2_MOUNT_##opt)
+/*
+ * Maximal mount counts between two filesystem checks
+ */
+#define EXT2_DFL_MAX_MNT_COUNT         20      /* Allow 20 mounts */
+#define EXT2_DFL_CHECKINTERVAL         0       /* Don't use interval check */
+
+/*
+ * Behaviour when detecting errors
+ */
+#define EXT2_ERRORS_CONTINUE           1       /* Continue execution */
+#define EXT2_ERRORS_RO                 2       /* Remount fs read-only */
+#define EXT2_ERRORS_PANIC              3       /* Panic */
+#define EXT2_ERRORS_DEFAULT            EXT2_ERRORS_CONTINUE
+
+/*
+ * Structure of the super block
+ */
+struct ext2_super_block {
+    __u32      s_inodes_count;         /* Inodes count */
+    __u32      s_blocks_count;         /* Blocks count */
+    __u32      s_r_blocks_count;       /* Reserved blocks count */
+    __u32      s_free_blocks_count;    /* Free blocks count */
+    __u32      s_free_inodes_count;    /* Free inodes count */
+    __u32      s_first_data_block;     /* First Data Block */
+    __u32      s_log_block_size;       /* Block size */
+    __s32      s_log_frag_size;        /* Fragment size */
+    __u32      s_blocks_per_group;     /* # Blocks per group */
+    __u32      s_frags_per_group;      /* # Fragments per group */
+    __u32      s_inodes_per_group;     /* # Inodes per group */
+    __u32      s_mtime;                /* Mount time */
+    __u32      s_wtime;                /* Write time */
+    __u16      s_mnt_count;            /* Mount count */
+    __s16      s_max_mnt_count;        /* Maximal mount count */
+    __u16      s_magic;                /* Magic signature */
+    __u16      s_state;                /* File system state */
+    __u16      s_errors;               /* Behaviour when detecting errors */
+    __u16      s_minor_rev_level;      /* minor revision level */
+    __u32      s_lastcheck;            /* time of last check */
+    __u32      s_checkinterval;        /* max. time between checks */
+    __u32      s_creator_os;           /* OS */
+    __u32      s_rev_level;            /* Revision level */
+    __u16      s_def_resuid;           /* Default uid for reserved blocks */
+    __u16      s_def_resgid;           /* Default gid for reserved blocks */
+    /*
+     * These fields are for EXT2_DYNAMIC_REV superblocks only.
+     *
+     * Note: the difference between the compatible feature set and
+     * the incompatible feature set is that if there is a bit set
+     * in the incompatible feature set that the kernel doesn't
+     * know about, it should refuse to mount the filesystem.
+     *
+     * e2fsck's requirements are more strict; if it doesn't know
+     * about a feature in either the compatible or incompatible
+     * feature set, it must abort and not try to meddle with
+     * things it doesn't understand...
+     */
+    __u32      s_first_ino;            /* First non-reserved inode */
+    __u16   s_inode_size;              /* size of inode structure */
+    __u16      s_block_group_nr;       /* block group # of this superblock */
+    __u32      s_feature_compat;       /* compatible feature set */
+    __u32      s_feature_incompat;     /* incompatible feature set */
+    __u32      s_feature_ro_compat;    /* readonly-compatible feature set */
+    __u8       s_uuid[16];             /* 128-bit uuid for volume */
+    char       s_volume_name[16];      /* volume name */
+    char       s_last_mounted[64];     /* directory where last mounted */
+    __u32      s_algorithm_usage_bitmap; /* For compression */
+    /*
+     * Performance hints.  Directory preallocation should only
+     * happen if the EXT2_COMPAT_PREALLOC flag is on.
+     */
+    __u8       s_prealloc_blocks;      /* Nr of blocks to try to preallocate*/
+    __u8       s_prealloc_dir_blocks;  /* Nr to preallocate for dirs */
+    __u16      s_padding1;
+    __u32      s_reserved[204];        /* Padding to the end of the block */
+};
+
+#ifdef __KERNEL__
+#define EXT2_SB(sb)    (&((sb)->u.ext2_sb))
+#else
+/* Assume that user mode programs are passing in an ext2fs superblock, not
+ * a kernel struct super_block.  This will allow us to call the feature-test
+ * macros from user land. */
+#define EXT2_SB(sb)    (sb)
+#endif
+
+/*
+ * Codes for operating systems
+ */
+#define EXT2_OS_LINUX          0
+#define EXT2_OS_HURD           1
+#define EXT2_OS_MASIX          2
+#define EXT2_OS_FREEBSD                3
+#define EXT2_OS_LITES          4
+
+/*
+ * Revision levels
+ */
+#define EXT2_GOOD_OLD_REV      0       /* The good old (original) format */
+#define EXT2_DYNAMIC_REV       1       /* V2 format w/ dynamic inode sizes */
+
+#define EXT2_CURRENT_REV       EXT2_GOOD_OLD_REV
+#define EXT2_MAX_SUPP_REV      EXT2_DYNAMIC_REV
+
+#define EXT2_GOOD_OLD_INODE_SIZE 128
+
+/*
+ * Feature set definitions
+ */
+
+#define EXT2_HAS_COMPAT_FEATURE(sb,mask)                       \
+       ( EXT2_SB(sb)->s_es->s_feature_compat & cpu_to_le32(mask) )
+#define EXT2_HAS_RO_COMPAT_FEATURE(sb,mask)                    \
+       ( EXT2_SB(sb)->s_es->s_feature_ro_compat & cpu_to_le32(mask) )
+#define EXT2_HAS_INCOMPAT_FEATURE(sb,mask)                     \
+       ( EXT2_SB(sb)->s_es->s_feature_incompat & cpu_to_le32(mask) )
+#define EXT2_SET_COMPAT_FEATURE(sb,mask)                       \
+       EXT2_SB(sb)->s_es->s_feature_compat |= cpu_to_le32(mask)
+#define EXT2_SET_RO_COMPAT_FEATURE(sb,mask)                    \
+       EXT2_SB(sb)->s_es->s_feature_ro_compat |= cpu_to_le32(mask)
+#define EXT2_SET_INCOMPAT_FEATURE(sb,mask)                     \
+       EXT2_SB(sb)->s_es->s_feature_incompat |= cpu_to_le32(mask)
+#define EXT2_CLEAR_COMPAT_FEATURE(sb,mask)                     \
+       EXT2_SB(sb)->s_es->s_feature_compat &= ~cpu_to_le32(mask)
+#define EXT2_CLEAR_RO_COMPAT_FEATURE(sb,mask)                  \
+       EXT2_SB(sb)->s_es->s_feature_ro_compat &= ~cpu_to_le32(mask)
+#define EXT2_CLEAR_INCOMPAT_FEATURE(sb,mask)                   \
+       EXT2_SB(sb)->s_es->s_feature_incompat &= ~cpu_to_le32(mask)
+
+#define EXT2_FEATURE_COMPAT_DIR_PREALLOC       0x0001
+#define EXT2_FEATURE_COMPAT_IMAGIC_INODES      0x0002
+#define EXT3_FEATURE_COMPAT_HAS_JOURNAL                0x0004
+#define EXT2_FEATURE_COMPAT_EXT_ATTR           0x0008
+#define EXT2_FEATURE_COMPAT_RESIZE_INO         0x0010
+#define EXT2_FEATURE_COMPAT_DIR_INDEX          0x0020
+#define EXT2_FEATURE_COMPAT_ANY                        0xffffffff
+
+#define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER    0x0001
+#define EXT2_FEATURE_RO_COMPAT_LARGE_FILE      0x0002
+#define EXT2_FEATURE_RO_COMPAT_BTREE_DIR       0x0004
+#define EXT2_FEATURE_RO_COMPAT_ANY             0xffffffff
+
+#define EXT2_FEATURE_INCOMPAT_COMPRESSION      0x0001
+#define EXT2_FEATURE_INCOMPAT_FILETYPE         0x0002
+
+#define EXT2_FEATURE_COMPAT_SUPP       0
+#define EXT2_FEATURE_INCOMPAT_SUPP     EXT2_FEATURE_INCOMPAT_FILETYPE
+#define EXT2_FEATURE_RO_COMPAT_SUPP    (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \
+                                        EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \
+                                        EXT2_FEATURE_RO_COMPAT_BTREE_DIR)
+#define EXT2_FEATURE_RO_COMPAT_UNSUPPORTED     ~EXT2_FEATURE_RO_COMPAT_SUPP
+#define EXT2_FEATURE_INCOMPAT_UNSUPPORTED      ~EXT2_FEATURE_INCOMPAT_SUPP
+
+/*
+ * Default values for user and/or group using reserved blocks
+ */
+#define        EXT2_DEF_RESUID         0
+#define        EXT2_DEF_RESGID         0
+
+/*
+ * Structure of a directory entry
+ */
+#define EXT2_NAME_LEN 255
+
+struct ext2_dir_entry {
+    __u32      inode;                  /* Inode number */
+    __u16      rec_len;                /* Directory entry length */
+    __u16      name_len;               /* Name length */
+    char       name[EXT2_NAME_LEN];    /* File name */
+};
+
+/*
+ * The new version of the directory entry.  Since EXT2 structures are
+ * stored in intel byte order, and the name_len field could never be
+ * bigger than 255 chars, it's safe to reclaim the extra byte for the
+ * file_type field.
+ */
+struct ext2_dir_entry_2 {
+    __u32      inode;                  /* Inode number */
+    __u16      rec_len;                /* Directory entry length */
+    __u8       name_len;               /* Name length */
+    __u8       file_type;
+    char       name[EXT2_NAME_LEN];    /* File name */
+};
+
+/*
+ * Ext2 directory file types.  Only the low 3 bits are used.  The
+ * other bits are reserved for now.
+ */
+enum {
+    EXT2_FT_UNKNOWN,
+    EXT2_FT_REG_FILE,
+    EXT2_FT_DIR,
+    EXT2_FT_CHRDEV,
+    EXT2_FT_BLKDEV,
+    EXT2_FT_FIFO,
+    EXT2_FT_SOCK,
+    EXT2_FT_SYMLINK,
+    EXT2_FT_MAX
+};
+
+/*
+ * EXT2_DIR_PAD defines the directory entries boundaries
+ *
+ * NOTE: It must be a multiple of 4
+ */
+#define EXT2_DIR_PAD                   4
+#define EXT2_DIR_ROUND                         (EXT2_DIR_PAD - 1)
+#define EXT2_DIR_REC_LEN(name_len)     (((name_len) + 8 + EXT2_DIR_ROUND) & \
+                                        ~EXT2_DIR_ROUND)
+
+#ifdef __KERNEL__
+/*
+ * Function prototypes
+ */
+
+/*
+ * Ok, these declarations are also in <linux/kernel.h> but none of the
+ * ext2 source programs needs to include it so they are duplicated here.
+ */
+# define NORET_TYPE    /**/
+# define ATTRIB_NORET  __attribute__((noreturn))
+# define NORET_AND     noreturn,
+
+/* balloc.c */
+extern int ext2_bg_has_super(struct super_block *sb, int group);
+extern unsigned long ext2_bg_num_gdb(struct super_block *sb, int group);
+extern int ext2_new_block (struct inode *, unsigned long,
+                               __u32 *, __u32 *, int *);
+extern void ext2_free_blocks (struct inode *, unsigned long,
+                                  unsigned long);
+extern unsigned long ext2_count_free_blocks (struct super_block *);
+extern void ext2_check_blocks_bitmap (struct super_block *);
+extern struct ext2_group_desc * ext2_get_group_desc(struct super_block * sb,
+                        unsigned int block_group,
+                        struct buffer_head ** bh);
+
+/* dir.c */
+extern int ext2_add_link (struct dentry *, struct inode *);
+extern ino_t ext2_inode_by_name(struct inode *, struct dentry *);
+extern int ext2_make_empty(struct inode *, struct inode *);
+extern struct ext2_dir_entry_2 * ext2_find_entry (struct inode *,struct dentry *, struct page **);
+extern int ext2_delete_entry (struct ext2_dir_entry_2 *, struct page *);
+extern int ext2_empty_dir (struct inode *);
+extern struct ext2_dir_entry_2 * ext2_dotdot (struct inode *, struct page **);
+extern void ext2_set_link(struct inode *, struct ext2_dir_entry_2 *, struct page *, struct inode *);
+
+/* fsync.c */
+extern int ext2_sync_file (struct file *, struct dentry *, int);
+extern int ext2_fsync_inode (struct inode *, int);
+
+/* ialloc.c */
+extern struct inode * ext2_new_inode (const struct inode *, int);
+extern void ext2_free_inode (struct inode *);
+extern unsigned long ext2_count_free_inodes (struct super_block *);
+extern void ext2_check_inodes_bitmap (struct super_block *);
+extern unsigned long ext2_count_free (struct buffer_head *, unsigned);
+
+/* inode.c */
+extern void ext2_read_inode (struct inode *);
+extern void ext2_write_inode (struct inode *, int);
+extern void ext2_put_inode (struct inode *);
+extern void ext2_delete_inode (struct inode *);
+extern int ext2_sync_inode (struct inode *);
+extern void ext2_discard_prealloc (struct inode *);
+extern void ext2_truncate (struct inode *);
+
+/* ioctl.c */
+extern int ext2_ioctl (struct inode *, struct file *, unsigned int,
+                           unsigned long);
+
+/* super.c */
+extern void ext2_error (struct super_block *, const char *, const char *, ...)
+    __attribute__ ((format (printf, 3, 4)));
+extern NORET_TYPE void ext2_panic (struct super_block *, const char *,
+                                       const char *, ...)
+    __attribute__ ((NORET_AND format (printf, 3, 4)));
+extern void ext2_warning (struct super_block *, const char *, const char *, ...)
+    __attribute__ ((format (printf, 3, 4)));
+extern void ext2_update_dynamic_rev (struct super_block *sb);
+extern void ext2_put_super (struct super_block *);
+extern void ext2_write_super (struct super_block *);
+extern int ext2_remount (struct super_block *, int *, char *);
+extern struct super_block * ext2_read_super (struct super_block *,void *,int);
+#ifndef __REACTOS__
+extern int ext2_statfs (struct super_block *, struct statfs *);
+#endif
+
+/*
+ * Inodes and files operations
+ */
+
+/* dir.c */
+extern struct file_operations ext2_dir_operations;
+
+/* file.c */
+extern struct inode_operations ext2_file_inode_operations;
+extern struct file_operations ext2_file_operations;
+
+/* inode.c */
+extern struct address_space_operations ext2_aops;
+
+/* namei.c */
+extern struct inode_operations ext2_dir_inode_operations;
+
+/* symlink.c */
+extern struct inode_operations ext2_fast_symlink_inode_operations;
+
+#endif /* __KERNEL__ */
+
+#endif /* _LINUX_EXT2_FS_H */
diff --git a/reactos/drivers/filesystems/ext2_new/inc/linux/atomic.h b/reactos/drivers/filesystems/ext2_new/inc/linux/atomic.h
new file mode 100644 (file)
index 0000000..d3db770
--- /dev/null
@@ -0,0 +1,155 @@
+#ifndef _LINUX_ATOMIC_H
+#define _LINUX_ATOMIC_H
+
+#include <linux/types.h>
+
+//
+// atomic
+//
+
+typedef struct {
+    volatile int counter;
+} atomic_t;
+
+#define ATOMIC_INIT(i) (i)
+
+/**
+ * atomic_read - read atomic variable
+ * @v: pointer of type atomic_t
+ *
+ * Atomically reads the value of @v.  Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */
+#define atomic_read(v)         ((v)->counter)
+
+/**
+ * atomic_set - set atomic variable
+ * @v: pointer of type atomic_t
+ * @i: required value
+ *
+ * Atomically sets the value of @v to @i.  Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */
+#define atomic_set(v,i) InterlockedExchange((PLONG)(&(v)->counter), (LONG)(i))
+
+/**
+ * atomic_add - add integer to atomic variable
+ * @i: integer value to add
+ * @v: pointer of type atomic_t
+ *
+ * Atomically adds @i to @v.  Note that the guaranteed useful range
+ * of an atomic_t is only 24 bits.
+ */
+static inline void atomic_add(int volatile i, atomic_t volatile *v)
+{
+    InterlockedExchangeAdd((PLONG)(&v->counter), (LONG) i);
+}
+
+/**
+ * atomic_sub - subtract the atomic variable
+ * @i: integer value to subtract
+ * @v: pointer of type atomic_t
+ *
+ * Atomically subtracts @i from @v.  Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */
+static inline void atomic_sub(int volatile i, atomic_t volatile *v)
+{
+    InterlockedExchangeAdd((PLONG)(&v->counter), (LONG) (-1*i));
+}
+
+/**
+ * atomic_sub_and_test - subtract value from variable and test result
+ * @i: integer value to subtract
+ * @v: pointer of type atomic_t
+ *
+ * Atomically subtracts @i from @v and returns
+ * true if the result is zero, or false for all
+ * other cases.  Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */
+static inline int atomic_sub_and_test(int volatile i, atomic_t volatile *v)
+{
+    int counter, result;
+
+    do {
+
+        counter = v->counter;
+        result = counter - i;
+
+    } while ( InterlockedCompareExchange(
+                  (PLONG) (&v->counter),
+                  (LONG) result,
+                  (LONG) counter) != counter);
+
+    return (result == 0);
+}
+
+/**
+ * atomic_inc - increment atomic variable
+ * @v: pointer of type atomic_t
+ *
+ * Atomically increments @v by 1.  Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */
+static inline void atomic_inc(atomic_t volatile *v)
+{
+    InterlockedIncrement((PLONG)(&v->counter));
+}
+
+/**
+ * atomic_dec - decrement atomic variable
+ * @v: pointer of type atomic_t
+ *
+ * Atomically decrements @v by 1.  Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */
+static inline void atomic_dec(atomic_t volatile *v)
+{
+    InterlockedDecrement((PLONG)(&v->counter));
+}
+
+/**
+ * atomic_dec_and_test - decrement and test
+ * @v: pointer of type atomic_t
+ *
+ * Atomically decrements @v by 1 and
+ * returns true if the result is 0, or false for all other
+ * cases.  Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */
+static inline int atomic_dec_and_test(atomic_t volatile *v)
+{
+    return (0 == InterlockedDecrement((PLONG)(&v->counter)));
+}
+
+/**
+ * atomic_inc_and_test - increment and test
+ * @v: pointer of type atomic_t
+ *
+ * Atomically increments @v by 1
+ * and returns true if the result is zero, or false for all
+ * other cases.  Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */
+static inline int atomic_inc_and_test(atomic_t volatile *v)
+{
+    return (0 == InterlockedIncrement((PLONG)(&v->counter)));
+}
+
+/**
+ * atomic_add_negative - add and test if negative
+ * @v: pointer of type atomic_t
+ * @i: integer value to add
+ *
+ * Atomically adds @i to @v and returns true
+ * if the result is negative, or false when
+ * result is greater than or equal to zero.  Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */
+static inline int atomic_add_negative(int volatile i, atomic_t volatile *v)
+{
+    return (InterlockedExchangeAdd((PLONG)(&v->counter), (LONG) i) + i);
+}
+
+#endif /* LINUX_ATOMIC_H */
\ No newline at end of file
diff --git a/reactos/drivers/filesystems/ext2_new/inc/linux/bit_spinlock.h b/reactos/drivers/filesystems/ext2_new/inc/linux/bit_spinlock.h
new file mode 100644 (file)
index 0000000..d8bd1bf
--- /dev/null
@@ -0,0 +1,95 @@
+#ifndef __LINUX_BIT_SPINLOCK_H
+#define __LINUX_BIT_SPINLOCK_H
+
+/*
+ *  bit-based spin_lock()
+ *
+ * Don't use this unless you really need to: spin_lock() and spin_unlock()
+ * are significantly faster.
+ */
+static inline void bit_spin_lock(int bitnum, unsigned long *addr)
+{
+    /*
+     * Assuming the lock is uncontended, this never enters
+     * the body of the outer loop. If it is contended, then
+     * within the inner loop a non-atomic test is used to
+     * busywait with less bus contention for a good time to
+     * attempt to acquire the lock bit.
+     */
+    preempt_disable();
+#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
+    while (unlikely(test_and_set_bit_lock(bitnum, addr))) {
+        while (test_bit(bitnum, addr)) {
+            preempt_enable();
+            cpu_relax();
+            preempt_disable();
+        }
+    }
+#endif
+    __acquire(bitlock);
+}
+
+/*
+ * Return true if it was acquired
+ */
+static inline int bit_spin_trylock(int bitnum, unsigned long *addr)
+{
+    preempt_disable();
+#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
+    if (unlikely(test_and_set_bit_lock(bitnum, addr))) {
+        preempt_enable();
+        return 0;
+    }
+#endif
+    __acquire(bitlock);
+    return 1;
+}
+
+/*
+ *  bit-based spin_unlock()
+ */
+static inline void bit_spin_unlock(int bitnum, unsigned long *addr)
+{
+#ifdef CONFIG_DEBUG_SPINLOCK
+    BUG_ON(!test_bit(bitnum, addr));
+#endif
+#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
+    clear_bit_unlock(bitnum, addr);
+#endif
+    preempt_enable();
+    __release(bitlock);
+}
+
+/*
+ *  bit-based spin_unlock()
+ *  non-atomic version, which can be used eg. if the bit lock itself is
+ *  protecting the rest of the flags in the word.
+ */
+static inline void __bit_spin_unlock(int bitnum, unsigned long *addr)
+{
+#ifdef CONFIG_DEBUG_SPINLOCK
+    BUG_ON(!test_bit(bitnum, addr));
+#endif
+#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
+    __clear_bit_unlock(bitnum, addr);
+#endif
+    preempt_enable();
+    __release(bitlock);
+}
+
+/*
+ * Return true if the lock is held.
+ */
+static inline int bit_spin_is_locked(int bitnum, unsigned long *addr)
+{
+#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
+    return test_bit(bitnum, addr);
+#elif defined CONFIG_PREEMPT
+    return preempt_count();
+#else
+    return 1;
+#endif
+}
+
+#endif /* __LINUX_BIT_SPINLOCK_H */
+
diff --git a/reactos/drivers/filesystems/ext2_new/inc/linux/bitops.h b/reactos/drivers/filesystems/ext2_new/inc/linux/bitops.h
new file mode 100644 (file)
index 0000000..cf10309
--- /dev/null
@@ -0,0 +1,280 @@
+#ifndef _LINUX_BITOPS_H
+#define _LINUX_BITOPS_H
+
+#include <ntifs.h>
+#include <linux/types.h>
+
+#ifdef __KERNEL__
+#define BIT(nr)                            (1 << (nr))
+#define BIT_MASK(nr)           (1 << ((nr) % BITS_PER_LONG))
+#define BIT_WORD(nr)           ((nr) / BITS_PER_LONG)
+#define BITS_TO_LONGS(nr)      DIV_ROUND_UP(nr, BITS_PER_LONG)
+#define BITS_PER_BYTE          8
+#endif
+
+/*
+ * Include this here because some architectures need generic_ffs/fls in
+ * scope
+ */
+
+/**
+ * find_first_zero_bit - find the first zero bit in a memory region
+ * @addr: The address to start the search at
+ * @size: The maximum size to search
+ *
+ * Returns the bit number of the first zero bit, not the number of the byte
+ * containing a bit.
+ */
+#define find_first_zero_bit(addr, size) find_next_zero_bit((addr), (size), 0)
+
+/**
+ * find_next_zero_bit - find the first zero bit in a memory region
+ * @addr: The address to base the search on
+ * @offset: The bit number to start searching at
+ * @size: The maximum size to search
+ */
+int find_next_zero_bit(const unsigned long *addr, int size, int offset);
+
+/**
+ * __ffs - find first bit in word.
+ * @word: The word to search
+ *
+ * Undefined if no bit exists, so code should check against 0 first.
+ */
+static inline unsigned long __ffs(unsigned long word)
+{
+    int num = 0;
+
+#if BITS_PER_LONG == 64
+    if ((word & 0xffffffff) == 0) {
+        num += 32;
+        word >>= 32;
+    }
+#endif
+    if ((word & 0xffff) == 0) {
+        num += 16;
+        word >>= 16;
+    }
+    if ((word & 0xff) == 0) {
+        num += 8;
+        word >>= 8;
+    }
+    if ((word & 0xf) == 0) {
+        num += 4;
+        word >>= 4;
+    }
+    if ((word & 0x3) == 0) {
+        num += 2;
+        word >>= 2;
+    }
+    if ((word & 0x1) == 0)
+        num += 1;
+    return num;
+}
+
+/**
+ * find_first_bit - find the first set bit in a memory region
+ * @addr: The address to start the search at
+ * @size: The maximum size to search
+ *
+ * Returns the bit number of the first set bit, not the number of the byte
+ * containing a bit.
+ */
+static inline unsigned find_first_bit(const unsigned long *addr, unsigned size)
+{
+    unsigned x = 0;
+
+    while (x < size) {
+        unsigned long val = *addr++;
+        if (val)
+            return __ffs(val) + x;
+        x += (sizeof(*addr)<<3);
+    }
+    return x;
+}
+
+/**
+ * find_next_bit - find the next set bit in a memory region
+ * @addr: The address to base the search on
+ * @offset: The bitnumber to start searching at
+ * @size: The maximum size to search
+ */
+
+/*
+ * ffz - find first zero in word.
+ * @word: The word to search
+ *
+ * Undefined if no zero exists, so code should check against ~0UL first.
+ */
+#define ffz(x)  __ffs(~(x))
+
+
+/**
+ * ffs - find first bit set
+ * @x: the word to search
+ *
+ * This is defined the same way as
+ * the libc and compiler builtin ffs routines, therefore
+ * differs in spirit from the above ffz (man ffs).
+ */
+static inline int ffs(int x)
+{
+    int r = 1;
+
+    if (!x)
+        return 0;
+    if (!(x & 0xffff)) {
+        x >>= 16;
+        r += 16;
+    }
+    if (!(x & 0xff)) {
+        x >>= 8;
+        r += 8;
+    }
+    if (!(x & 0xf)) {
+        x >>= 4;
+        r += 4;
+    }
+    if (!(x & 3)) {
+        x >>= 2;
+        r += 2;
+    }
+    if (!(x & 1)) {
+        x >>= 1;
+        r += 1;
+    }
+    return r;
+}
+
+/**
+ * fls - find last (most-significant) bit set
+ * @x: the word to search
+ *
+ * This is defined the same way as ffs.
+ * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
+ */
+
+static inline int fls(int x)
+{
+    int r = 32;
+
+    if (!x)
+        return 0;
+    if (!(x & 0xffff0000u)) {
+        x <<= 16;
+        r -= 16;
+    }
+    if (!(x & 0xff000000u)) {
+        x <<= 8;
+        r -= 8;
+    }
+    if (!(x & 0xf0000000u)) {
+        x <<= 4;
+        r -= 4;
+    }
+    if (!(x & 0xc0000000u)) {
+        x <<= 2;
+        r -= 2;
+    }
+    if (!(x & 0x80000000u)) {
+        x <<= 1;
+        r -= 1;
+    }
+    return r;
+}
+
+static inline int fls64(__u64 x)
+{
+    __u32 h = (__u32) (x >> 32);
+    if (h)
+        return fls(h) + 32;
+    return fls((int)x);
+}
+
+#define for_each_bit(bit, addr, size) \
+       for ((bit) = find_first_bit((addr), (size)); \
+            (bit) < (size); \
+            (bit) = find_next_bit((addr), (size), (bit) + 1))
+
+
+static __inline int get_bitmask_order(unsigned int count)
+{
+    int order;
+
+    order = fls(count);
+    return order;      /* We could be slightly more clever with -1 here... */
+}
+
+static __inline int get_count_order(unsigned int count)
+{
+    int order;
+
+    order = fls(count) - 1;
+    if (count & (count - 1))
+        order++;
+    return order;
+}
+
+
+/**
+ * rol32 - rotate a 32-bit value left
+ * @word: value to rotate
+ * @shift: bits to roll
+ */
+static inline __u32 rol32(__u32 word, unsigned int shift)
+{
+    return (word << shift) | (word >> (32 - shift));
+}
+
+/**
+ * ror32 - rotate a 32-bit value right
+ * @word: value to rotate
+ * @shift: bits to roll
+ */
+static inline __u32 ror32(__u32 word, unsigned int shift)
+{
+    return (word >> shift) | (word << (32 - shift));
+}
+
+static inline unsigned fls_long(unsigned long l)
+{
+    if (sizeof(l) == 4)
+        return fls(l);
+    return fls64(l);
+}
+
+/*
+ * hweightN: returns the hamming weight (i.e. the number
+ * of bits set) of a N-bit word
+ */
+
+static inline unsigned long hweight32(unsigned long w)
+{
+    unsigned int res = (w & 0x55555555) + ((w >> 1) & 0x55555555);
+    res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
+    res = (res & 0x0F0F0F0F) + ((res >> 4) & 0x0F0F0F0F);
+    res = (res & 0x00FF00FF) + ((res >> 8) & 0x00FF00FF);
+    return (res & 0x0000FFFF) + ((res >> 16) & 0x0000FFFF);
+}
+
+static inline unsigned long hweight64(__u64 w)
+{
+#if BITS_PER_LONG < 64
+    return hweight32((unsigned int)(w >> 32)) + hweight32((unsigned int)w);
+#else
+    u64 res;
+    res = (w & 0x5555555555555555U) + ((w >> 1) & 0x5555555555555555U);
+    res = (res & 0x3333333333333333U) + ((res >> 2) & 0x3333333333333333U);
+    res = (res & 0x0F0F0F0F0F0F0F0FU) + ((res >> 4) & 0x0F0F0F0F0F0F0F0FU);
+    res = (res & 0x00FF00FF00FF00FFU) + ((res >> 8) & 0x00FF00FF00FF00FFU);
+    res = (res & 0x0000FFFF0000FFFFU) + ((res >> 16) & 0x0000FFFF0000FFFFU);
+    return (res & 0x00000000FFFFFFFFU) + ((res >> 32) & 0x00000000FFFFFFFFU);
+#endif
+}
+
+static inline unsigned long hweight_long(unsigned long w)
+{
+    return sizeof(w) == 4 ? hweight32(w) : hweight64(w);
+}
+
+#endif
diff --git a/reactos/drivers/filesystems/ext2_new/inc/linux/config.h b/reactos/drivers/filesystems/ext2_new/inc/linux/config.h
new file mode 100644 (file)
index 0000000..1d0a4be
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef LINUX_CONFIG_H
+#define LINUX_CONFIG_H
+
+#define EXT2_HTREE_INDEX 1
+//#undef EXT2_HTREE_INDEX
+
+#endif /* LINUX_CONFIG_H */
\ No newline at end of file
diff --git a/reactos/drivers/filesystems/ext2_new/inc/linux/errno.h b/reactos/drivers/filesystems/ext2_new/inc/linux/errno.h
new file mode 100644 (file)
index 0000000..5173d2a
--- /dev/null
@@ -0,0 +1,152 @@
+#ifndef _I386_ERRNO_H
+#define _I386_ERRNO_H
+
+#include <errno.h>
+
+#ifndef __REACTOS__
+#define        EPERM            1      /* Operation not permitted */
+#define        ENOENT           2      /* No such file or directory */
+#define        ESRCH            3      /* No such process */
+#define        EINTR            4      /* Interrupted system call */
+#define        EIO          5      /* I/O error */
+#define        ENXIO            6      /* No such device or address */
+#define        E2BIG            7      /* Arg list too long */
+#define        ENOEXEC          8      /* Exec format error */
+#define        EBADF            9      /* Bad file number */
+#define        ECHILD          10      /* No child processes */
+#define        EAGAIN          11      /* Try again */
+#define        ENOMEM          12      /* Out of memory */
+#define        EACCES          13      /* Permission denied */
+#define        EFAULT          14      /* Bad address */
+#define        ENOTBLK         15      /* Block device required */
+#define        EBUSY           16      /* Device or resource busy */
+#define        EEXIST          17      /* File exists */
+#define        EXDEV           18      /* Cross-device link */
+#define        ENODEV          19      /* No such device */
+#define        ENOTDIR         20      /* Not a directory */
+#define        EISDIR          21      /* Is a directory */
+#define        EINVAL          22      /* Invalid argument */
+#define        ENFILE          23      /* File table overflow */
+#define        EMFILE          24      /* Too many open files */
+#define        ENOTTY          25      /* Not a typewriter */
+#define        ETXTBSY         26      /* Text file busy */
+#define        EFBIG           27      /* File too large */
+#define        ENOSPC          28      /* No space left on device */
+#define        ESPIPE          29      /* Illegal seek */
+#define        EROFS           30      /* Read-only file system */
+#define        EMLINK          31      /* Too many links */
+#define        EPIPE           32      /* Broken pipe */
+#define        EDOM            33      /* Math argument out of domain of func */
+#define        ERANGE          34      /* Math result not representable */
+#define        ELOOP           40      /* Too many symbolic links encountered */
+#define        EWOULDBLOCK     EAGAIN  /* Operation would block */
+#define        ENOMSG          42      /* No message of desired type */
+#define        EIDRM           43      /* Identifier removed */
+#define        ECHRNG          44      /* Channel number out of range */
+#define        EL2NSYNC        45      /* Level 2 not synchronized */
+#define        EL3HLT          46      /* Level 3 halted */
+#define        EL3RST          47      /* Level 3 reset */
+#define        ELNRNG          48      /* Link number out of range */
+#define        EUNATCH         49      /* Protocol driver not attached */
+#define        ENOCSI          50      /* No CSI structure available */
+#define        EL2HLT          51      /* Level 2 halted */
+#define        EBADE           52      /* Invalid exchange */
+#define        EBADR           53      /* Invalid request descriptor */
+#define        EXFULL          54      /* Exchange full */
+#define        ENOANO          55      /* No anode */
+#define        EBADRQC         56      /* Invalid request code */
+#define        EBADSLT         57      /* Invalid slot */
+
+#define        EDEADLOCK       EDEADLK
+
+#define        EBFONT          59      /* Bad font file format */
+#define        ENOSTR          60      /* Device not a stream */
+#define        ENODATA         61      /* No data available */
+#define        ETIME           62      /* Timer expired */
+#define        ENOSR           63      /* Out of streams resources */
+#define        ENONET          64      /* Machine is not on the network */
+#define        ENOPKG          65      /* Package not installed */
+#define        EREMOTE         66      /* Object is remote */
+#define        ENOLINK         67      /* Link has been severed */
+#define        EADV            68      /* Advertise error */
+#define        ESRMNT          69      /* Srmount error */
+#define        ECOMM           70      /* Communication error on send */
+#define        EPROTO          71      /* Protocol error */
+#define        EMULTIHOP       72      /* Multihop attempted */
+#define        EDOTDOT         73      /* RFS specific error */
+#endif
+#define        EBADMSG         74      /* Not a data message */
+#ifndef __REACTOS__
+#define        EOVERFLOW       75      /* Value too large for defined data type */
+#define        ENOTUNIQ        76      /* Name not unique on network */
+#define        EBADFD          77      /* File descriptor in bad state */
+#define        EREMCHG         78      /* Remote address changed */
+#define        ELIBACC         79      /* Can not access a needed shared library */
+#define        ELIBBAD         80      /* Accessing a corrupted shared library */
+#define        ELIBSCN         81      /* .lib section in a.out corrupted */
+#define        ELIBMAX         82      /* Attempting to link in too many shared libraries */
+#define        ELIBEXEC        83      /* Cannot exec a shared library directly */
+#define        ERESTART        85      /* Interrupted system call should be restarted */
+#define        ESTRPIPE        86      /* Streams pipe error */
+#define        EUSERS          87      /* Too many users */
+#define        ENOTSOCK        88      /* Socket operation on non-socket */
+#define        EDESTADDRREQ    89      /* Destination address required */
+#endif
+#define        EMSGSIZE        90      /* Message too long */
+#ifndef __REACTOS__
+#define        EPROTOTYPE      91      /* Protocol wrong type for socket */
+#define        ENOPROTOOPT     92      /* Protocol not available */
+#define        EPROTONOSUPPORT 93      /* Protocol not supported */
+#define        ESOCKTNOSUPPORT 94      /* Socket type not supported */
+#endif
+#define        EOPNOTSUPP      95      /* Operation not supported on transport endpoint */
+#ifndef __REACTOS__
+#define        EPFNOSUPPORT    96      /* Protocol family not supported */
+#define        EAFNOSUPPORT    97      /* Address family not supported by protocol */
+#endif
+#define        EADDRINUSE      98      /* Address already in use */
+#define        EADDRNOTAVAIL   99      /* Cannot assign requested address */
+#define        ENETDOWN        100     /* Network is down */
+#define        ENETUNREACH     101     /* Network is unreachable */
+#define        ENETRESET       102     /* Network dropped connection because of reset */
+#define        ECONNABORTED    103     /* Software caused connection abort */
+#define        ECONNRESET      104     /* Connection reset by peer */
+#define        ENOBUFS         105     /* No buffer space available */
+#define        EISCONN         106     /* Transport endpoint is already connected */
+#define        ENOTCONN        107     /* Transport endpoint is not connected */
+#define        ESHUTDOWN       108     /* Cannot send after transport endpoint shutdown */
+#define        ETOOMANYREFS    109     /* Too many references: cannot splice */
+#define        ETIMEDOUT       110     /* Connection timed out */
+#define        ECONNREFUSED    111     /* Connection refused */
+#define        EHOSTDOWN       112     /* Host is down */
+#define        EHOSTUNREACH    113     /* No route to host */
+#define        EALREADY        114     /* Operation already in progress */
+#define        EINPROGRESS     115     /* Operation now in progress */
+#define        ESTALE          116     /* Stale NFS file handle */
+#define        EUCLEAN         117     /* Structure needs cleaning */
+#define        ENOTNAM         118     /* Not a XENIX named type file */
+#define        ENAVAIL         119     /* No XENIX semaphores available */
+#define        EISNAM          120     /* Is a named type file */
+#define        EREMOTEIO       121     /* Remote I/O error */
+#define        EDQUOT          122     /* Quota exceeded */
+
+#define        ENOMEDIUM       123     /* No medium found */
+#define        EMEDIUMTYPE     124     /* Wrong medium type */
+
+/* Should never be seen by user programs */
+#define ERESTARTSYS    512
+#define ERESTARTNOINTR 513
+#define ERESTARTNOHAND 514     /* restart if no handler.. */
+#define ENOIOCTLCMD    515     /* No ioctl command */
+
+/* Defined for the NFSv3 protocol */
+#define EBADHANDLE     521     /* Illegal NFS file handle */
+#define ENOTSYNC       522     /* Update synchronization mismatch */
+#define EBADCOOKIE     523     /* Cookie is stale */
+#define ENOTSUPP       524     /* Operation is not supported */
+#define ETOOSMALL      525     /* Buffer or request is too small */
+#define ESERVERFAULT   526     /* An untranslatable error occurred */
+#define EBADTYPE       527     /* Type not supported by server */
+#define EJUKEBOX       528     /* Request initiated, but will not complete before timeout */
+
+#endif
diff --git a/reactos/drivers/filesystems/ext2_new/inc/linux/ext3_fs.h b/reactos/drivers/filesystems/ext2_new/inc/linux/ext3_fs.h
new file mode 100644 (file)
index 0000000..2d0227d
--- /dev/null
@@ -0,0 +1,1040 @@
+/*
+ *  linux/include/linux/ext3_fs.h
+ *
+ * Copyright (C) 1992, 1993, 1994, 1995
+ * Remy Card (card@masi.ibp.fr)
+ * Laboratoire MASI - Institut Blaise Pascal
+ * Universite Pierre et Marie Curie (Paris VI)
+ *
+ *  from
+ *
+ *  linux/include/linux/minix_fs.h
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ */
+
+#ifndef _LINUX_EXT3_FS_H
+#define _LINUX_EXT3_FS_H
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/magic.h>
+
+/*
+ * The second extended filesystem constants/structures
+ */
+
+/*
+ * Define EXT3FS_DEBUG to produce debug messages
+ */
+#undef EXT3FS_DEBUG
+
+/*
+ * Define EXT3_RESERVATION to reserve data blocks for expanding files
+ */
+#define EXT3_DEFAULT_RESERVE_BLOCKS     8
+/*max window size: 1024(direct blocks) + 3([t,d]indirect blocks) */
+#define EXT3_MAX_RESERVE_BLOCKS         1027
+#define EXT3_RESERVE_WINDOW_NOT_ALLOCATED 0
+
+/*
+ * Debug code
+ */
+#ifdef EXT3FS_DEBUG
+#define ext3_debug(f, a...)                                            \
+       do {                                                            \
+               printk (KERN_DEBUG "EXT3-fs DEBUG (%s, %d): %s:",       \
+                       __FILE__, __LINE__, __FUNCTION__);              \
+               printk (KERN_DEBUG f, ## a);                            \
+       } while (0)
+#else
+#define ext3_debug
+#endif
+
+/*
+ * Special inodes numbers
+ */
+#define        EXT3_BAD_INO             1      /* Bad blocks inode */
+#define EXT3_ROOT_INO           2      /* Root inode */
+#define EXT3_BOOT_LOADER_INO    5      /* Boot loader inode */
+#define EXT3_UNDEL_DIR_INO      6      /* Undelete directory inode */
+#define EXT3_RESIZE_INO                 7      /* Reserved group descriptors inode */
+#define EXT3_JOURNAL_INO        8      /* Journal inode */
+
+/* First non-reserved inode for old ext3 filesystems */
+#define EXT3_GOOD_OLD_FIRST_INO        11
+
+/*
+ * Maximal count of links to a file
+ */
+#define EXT3_LINK_MAX          32000
+
+/*
+ * Macro-instructions used to manage several block sizes
+ */
+#define EXT3_MIN_BLOCK_SIZE            1024
+#define        EXT3_MAX_BLOCK_SIZE             65536
+#define EXT3_MIN_BLOCK_LOG_SIZE                10
+#ifdef __KERNEL__
+# define EXT3_BLOCK_SIZE(s)            ((s)->s_blocksize)
+#else
+# define EXT3_BLOCK_SIZE(s)            (EXT3_MIN_BLOCK_SIZE << (s)->s_log_block_size)
+#endif
+#define        EXT3_ADDR_PER_BLOCK(s)          (EXT3_BLOCK_SIZE(s) / sizeof (__u32))
+#ifdef __KERNEL__
+# define EXT3_BLOCK_SIZE_BITS(s)       ((s)->s_blocksize_bits)
+#else
+# define EXT3_BLOCK_SIZE_BITS(s)       ((s)->s_log_block_size + 10)
+#endif
+#ifdef __KERNEL__
+#define        EXT3_ADDR_PER_BLOCK_BITS(s)     (EXT3_SB(s)->s_addr_per_block_bits)
+#define EXT3_INODE_SIZE(s)             (EXT3_SB(s)->s_inode_size)
+#define EXT3_FIRST_INO(s)              (EXT3_SB(s)->s_first_ino)
+#else
+#define EXT3_INODE_SIZE(s)     (((s)->s_rev_level == EXT3_GOOD_OLD_REV) ? \
+                                EXT3_GOOD_OLD_INODE_SIZE : \
+                                (s)->s_inode_size)
+#define EXT3_FIRST_INO(s)      (((s)->s_rev_level == EXT3_GOOD_OLD_REV) ? \
+                                EXT3_GOOD_OLD_FIRST_INO : \
+                                (s)->s_first_ino)
+#endif
+
+/*
+ * Macro-instructions used to manage fragments
+ */
+#define EXT3_MIN_FRAG_SIZE             1024
+#define        EXT3_MAX_FRAG_SIZE              4096
+#define EXT3_MIN_FRAG_LOG_SIZE           10
+#ifdef __KERNEL__
+# define EXT3_FRAG_SIZE(s)             (EXT3_SB(s)->s_frag_size)
+# define EXT3_FRAGS_PER_BLOCK(s)       (EXT3_SB(s)->s_frags_per_block)
+#else
+# define EXT3_FRAG_SIZE(s)             (EXT3_MIN_FRAG_SIZE << (s)->s_log_frag_size)
+# define EXT3_FRAGS_PER_BLOCK(s)       (EXT3_BLOCK_SIZE(s) / EXT3_FRAG_SIZE(s))
+#endif
+
+/*
+ * Structure of a blocks group descriptor
+ */
+struct ext3_group_desc
+{
+    __le32     bg_block_bitmap;                /* Blocks bitmap block */
+    __le32     bg_inode_bitmap;                /* Inodes bitmap block */
+    __le32     bg_inode_table;         /* Inodes table block */
+    __le16     bg_free_blocks_count;   /* Free blocks count */
+    __le16     bg_free_inodes_count;   /* Free inodes count */
+    __le16     bg_used_dirs_count;     /* Directories count */
+    __u16      bg_pad;
+    __le32     bg_reserved[3];
+};
+
+/*
+ * Structure of a blocks group descriptor
+ */
+struct ext4_group_desc
+{
+    __le32     bg_block_bitmap;        /* Blocks bitmap block */
+    __le32     bg_inode_bitmap;        /* Inodes bitmap block */
+    __le32     bg_inode_table; /* Inodes table block */
+    __le16     bg_free_blocks_count;/* Free blocks count */
+    __le16     bg_free_inodes_count;/* Free inodes count */
+    __le16     bg_used_dirs_count;     /* Directories count */
+    __le16     bg_flags;               /* EXT4_BG_flags (INODE_UNINIT, etc) */
+    __u32      bg_reserved[2];         /* Likely block/inode bitmap checksum */
+    __le16  bg_itable_unused;  /* Unused inodes count */
+    __le16  bg_checksum;               /* crc16(sb_uuid+group+desc) */
+    __le32     bg_block_bitmap_hi;     /* Blocks bitmap block MSB */
+    __le32     bg_inode_bitmap_hi;     /* Inodes bitmap block MSB */
+    __le32     bg_inode_table_hi;      /* Inodes table block MSB */
+    __le16     bg_free_blocks_count_hi;/* Free blocks count MSB */
+    __le16     bg_free_inodes_count_hi;/* Free inodes count MSB */
+    __le16     bg_used_dirs_count_hi;  /* Directories count MSB */
+    __le16  bg_itable_unused_hi;    /* Unused inodes count MSB */
+    __u32      bg_reserved2[3];
+};
+
+/*
+ * Structure of a flex block group info
+ */
+
+struct flex_groups {
+    __u32 free_inodes;
+    __u32 free_blocks;
+};
+
+#define EXT4_BG_INODE_UNINIT   0x0001 /* Inode table/bitmap not in use */
+#define EXT4_BG_BLOCK_UNINIT   0x0002 /* Block bitmap not in use */
+#define EXT4_BG_INODE_ZEROED   0x0004 /* On-disk itable initialized to zero */
+
+#define EXT4_MIN_BLOCK_SIZE            1024
+#define EXT4_MIN_DESC_SIZE             32
+#define EXT4_MIN_DESC_SIZE_64BIT       64
+#define        EXT4_MAX_DESC_SIZE              EXT4_MIN_BLOCK_SIZE
+
+#define EXT4_DESC_SIZE(s)              (EXT3_SB(s)->s_desc_size)
+
+/*
+ * Macro-instructions used to manage group descriptors
+ */
+#ifdef __KERNEL__
+# define EXT3_BLOCKS_PER_GROUP(s)      (EXT3_SB(s)->s_blocks_per_group)
+# define EXT3_DESC_PER_BLOCK(s)                (EXT3_SB(s)->s_desc_per_block)
+# define EXT3_INODES_PER_GROUP(s)      (EXT3_SB(s)->s_inodes_per_group)
+# define EXT3_DESC_PER_BLOCK_BITS(s)   (EXT3_SB(s)->s_desc_per_block_bits)
+# define EXT4_BLOCKS_PER_GROUP(s)      (EXT3_SB(s)->s_blocks_per_group)
+# define EXT4_DESC_PER_BLOCK(s)                (EXT3_SB(s)->s_desc_per_block)
+# define EXT4_INODES_PER_GROUP(s)      (EXT3_SB(s)->s_inodes_per_group)
+# define EXT4_DESC_PER_BLOCK_BITS(s)   (EXT3_SB(s)->s_desc_per_block_bits)
+#else
+# define EXT3_BLOCKS_PER_GROUP(s)      ((s)->s_blocks_per_group)
+# define EXT3_DESC_PER_BLOCK(s)                (EXT3_BLOCK_SIZE(s) / sizeof (struct ext3_group_desc))
+# define EXT3_INODES_PER_GROUP(s)      ((s)->s_inodes_per_group)
+#endif
+
+/*
+ * Constants relative to the data blocks
+ */
+#define        EXT3_NDIR_BLOCKS                12
+#define        EXT3_IND_BLOCK                  EXT3_NDIR_BLOCKS
+#define        EXT3_DIND_BLOCK                 (EXT3_IND_BLOCK + 1)
+#define        EXT3_TIND_BLOCK                 (EXT3_DIND_BLOCK + 1)
+#define        EXT3_N_BLOCKS                   (EXT3_TIND_BLOCK + 1)
+
+/*
+ * Inode flags
+ */
+#define        EXT3_SECRM_FL                   0x00000001 /* Secure deletion */
+#define        EXT3_UNRM_FL                    0x00000002 /* Undelete */
+#define        EXT3_COMPR_FL                   0x00000004 /* Compress file */
+#define EXT3_SYNC_FL                   0x00000008 /* Synchronous updates */
+#define EXT3_IMMUTABLE_FL              0x00000010 /* Immutable file */
+#define EXT3_APPEND_FL                 0x00000020 /* writes to file may only append */
+#define EXT3_NODUMP_FL                 0x00000040 /* do not dump file */
+#define EXT3_NOATIME_FL                        0x00000080 /* do not update atime */
+/* Reserved for compression usage... */
+#define EXT3_DIRTY_FL                  0x00000100
+#define EXT3_COMPRBLK_FL               0x00000200 /* One or more compressed clusters */
+#define EXT3_NOCOMPR_FL                        0x00000400 /* Don't compress */
+#define EXT3_ECOMPR_FL                 0x00000800 /* Compression error */
+/* End compression flags --- maybe not all used */
+#define EXT3_INDEX_FL                  0x00001000 /* hash-indexed directory */
+#define EXT3_IMAGIC_FL                 0x00002000 /* AFS directory */
+#define EXT3_JOURNAL_DATA_FL           0x00004000 /* file data should be journaled */
+#define EXT3_NOTAIL_FL                 0x00008000 /* file tail should not be merged */
+#define EXT3_DIRSYNC_FL                        0x00010000 /* dirsync behaviour (directories only) */
+#define EXT3_TOPDIR_FL                 0x00020000 /* Top of directory hierarchies*/
+#define EXT3_RESERVED_FL               0x80000000 /* reserved for ext3 lib */
+
+#define EXT3_FL_USER_VISIBLE           0x0003DFFF /* User visible flags */
+#define EXT3_FL_USER_MODIFIABLE                0x000380FF /* User modifiable flags */
+
+/*
+ * Inode dynamic state flags
+ */
+#define EXT3_STATE_JDATA               0x00000001 /* journaled data exists */
+#define EXT3_STATE_NEW                 0x00000002 /* inode is newly created */
+#define EXT3_STATE_XATTR               0x00000004 /* has in-inode xattrs */
+
+
+/*
+ * Ext4 Inode flags
+ */
+#define        EXT4_SECRM_FL                   0x00000001 /* Secure deletion */
+#define        EXT4_UNRM_FL                    0x00000002 /* Undelete */
+#define        EXT4_COMPR_FL                   0x00000004 /* Compress file */
+#define EXT4_SYNC_FL                   0x00000008 /* Synchronous updates */
+#define EXT4_IMMUTABLE_FL              0x00000010 /* Immutable file */
+#define EXT4_APPEND_FL                 0x00000020 /* writes to file may only append */
+#define EXT4_NODUMP_FL                 0x00000040 /* do not dump file */
+#define EXT4_NOATIME_FL                        0x00000080 /* do not update atime */
+/* Reserved for compression usage... */
+#define EXT4_DIRTY_FL                  0x00000100
+#define EXT4_COMPRBLK_FL               0x00000200 /* One or more compressed clusters */
+#define EXT4_NOCOMPR_FL                        0x00000400 /* Don't compress */
+#define EXT4_ECOMPR_FL                 0x00000800 /* Compression error */
+/* End compression flags --- maybe not all used */
+#define EXT4_INDEX_FL                  0x00001000 /* hash-indexed directory */
+#define EXT4_IMAGIC_FL                 0x00002000 /* AFS directory */
+#define EXT4_JOURNAL_DATA_FL           0x00004000 /* file data should be journaled */
+#define EXT4_NOTAIL_FL                 0x00008000 /* file tail should not be merged */
+#define EXT4_DIRSYNC_FL                        0x00010000 /* dirsync behaviour (directories only) */
+#define EXT4_TOPDIR_FL                 0x00020000 /* Top of directory hierarchies*/
+#define EXT4_HUGE_FILE_FL               0x00040000 /* Set to each huge file */
+#define EXT4_EXTENTS_FL                        0x00080000 /* Inode uses extents */
+#define EXT4_EXT_MIGRATE               0x00100000 /* Inode is migrating */
+#define EXT4_RESERVED_FL               0x80000000 /* reserved for ext4 lib */
+
+#define EXT4_FL_USER_VISIBLE           0x000BDFFF /* User visible flags */
+#define EXT4_FL_USER_MODIFIABLE                0x000B80FF /* User modifiable flags */
+
+/* Used to pass group descriptor data when online resize is done */
+struct ext3_new_group_input {
+    __u32 group;            /* Group number for this data */
+    __u32 block_bitmap;     /* Absolute block number of block bitmap */
+    __u32 inode_bitmap;     /* Absolute block number of inode bitmap */
+    __u32 inode_table;      /* Absolute block number of inode table start */
+    __u32 blocks_count;     /* Total number of blocks in this group */
+    __u16 reserved_blocks;  /* Number of reserved blocks in this group */
+    __u16 unused;
+};
+
+/* The struct ext3_new_group_input in kernel space, with free_blocks_count */
+struct ext3_new_group_data {
+    __u32 group;
+    __u32 block_bitmap;
+    __u32 inode_bitmap;
+    __u32 inode_table;
+    __u32 blocks_count;
+    __u16 reserved_blocks;
+    __u16 unused;
+    __u32 free_blocks_count;
+};
+
+
+/*
+ * ioctl commands
+ */
+#define        EXT3_IOC_GETFLAGS               FS_IOC_GETFLAGS
+#define        EXT3_IOC_SETFLAGS               FS_IOC_SETFLAGS
+#define        EXT3_IOC_GETVERSION             _IOR('f', 3, long)
+#define        EXT3_IOC_SETVERSION             _IOW('f', 4, long)
+#define EXT3_IOC_GROUP_EXTEND          _IOW('f', 7, unsigned long)
+#define EXT3_IOC_GROUP_ADD             _IOW('f', 8,struct ext3_new_group_input)
+#define        EXT3_IOC_GETVERSION_OLD         FS_IOC_GETVERSION
+#define        EXT3_IOC_SETVERSION_OLD         FS_IOC_SETVERSION
+#ifdef CONFIG_JBD_DEBUG
+#define EXT3_IOC_WAIT_FOR_READONLY     _IOR('f', 99, long)
+#endif
+#define EXT3_IOC_GETRSVSZ              _IOR('f', 5, long)
+#define EXT3_IOC_SETRSVSZ              _IOW('f', 6, long)
+
+/*
+ * ioctl commands in 32 bit emulation
+ */
+#define EXT3_IOC32_GETFLAGS            FS_IOC32_GETFLAGS
+#define EXT3_IOC32_SETFLAGS            FS_IOC32_SETFLAGS
+#define EXT3_IOC32_GETVERSION          _IOR('f', 3, int)
+#define EXT3_IOC32_SETVERSION          _IOW('f', 4, int)
+#define EXT3_IOC32_GETRSVSZ            _IOR('f', 5, int)
+#define EXT3_IOC32_SETRSVSZ            _IOW('f', 6, int)
+#define EXT3_IOC32_GROUP_EXTEND                _IOW('f', 7, unsigned int)
+#ifdef CONFIG_JBD_DEBUG
+#define EXT3_IOC32_WAIT_FOR_READONLY   _IOR('f', 99, int)
+#endif
+#define EXT3_IOC32_GETVERSION_OLD      FS_IOC32_GETVERSION
+#define EXT3_IOC32_SETVERSION_OLD      FS_IOC32_SETVERSION
+
+
+/*
+ *  Mount options
+ */
+struct ext3_mount_options {
+    unsigned long s_mount_opt;
+    uid_t s_resuid;
+    gid_t s_resgid;
+    unsigned long s_commit_interval;
+#ifdef CONFIG_QUOTA
+    int s_jquota_fmt;
+    char *s_qf_names[MAXQUOTAS];
+#endif
+};
+
+/*
+ * Structure of an inode on the disk
+ */
+struct ext3_inode {
+    __le16     i_mode;         /* File mode */
+    __le16     i_uid;          /* Low 16 bits of Owner Uid */
+    __le32     i_size;         /* Size in bytes */
+    __le32     i_atime;        /* Access time */
+    __le32     i_ctime;        /* Creation time */
+    __le32     i_mtime;        /* Modification time */
+    __le32     i_dtime;        /* Deletion Time */
+    __le16     i_gid;          /* Low 16 bits of Group Id */
+    __le16     i_links_count;  /* Links count */
+    __le32     i_blocks;       /* Blocks count */
+    __le32     i_flags;        /* File flags */
+    union {
+        struct {
+            __le32  l_i_version;
+        } linux1;
+        struct {
+            __u32  h_i_translator;
+        } hurd1;
+        struct {
+            __u32  m_i_reserved1;
+        } masix1;
+    } osd1;                            /* OS dependent 1 */
+    __le32     i_block[EXT3_N_BLOCKS];/* Pointers to blocks */
+    __le32     i_generation;   /* File version (for NFS) */
+    __le32     i_file_acl_lo;  /* File ACL */
+    __le32     i_size_high;
+    __le32     i_obso_faddr;   /* Obsoleted fragment address */
+    union {
+        struct {
+            __le16     l_i_blocks_high; /* were l_i_reserved1 */
+            __le16     l_i_file_acl_high;
+            __le16     l_i_uid_high;   /* these 2 fields */
+            __le16     l_i_gid_high;   /* were reserved2[0] */
+            __u32      l_i_reserved2;
+        } linux2;
+        struct {
+            __le16     h_i_reserved1;  /* Obsoleted fragment number/size which are removed in ext4 */
+            __u16      h_i_mode_high;
+            __u16      h_i_uid_high;
+            __u16      h_i_gid_high;
+            __u32      h_i_author;
+        } hurd2;
+        struct {
+            __le16     h_i_reserved1;  /* Obsoleted fragment number/size which are removed in ext4 */
+            __le16     m_i_file_acl_high;
+            __u32      m_i_reserved2[2];
+        } masix2;
+    } osd2;                            /* OS dependent 2 */
+    __le16     i_extra_isize;
+    __le16     i_pad1;
+    __le32  i_ctime_extra;  /* extra Change time      (nsec << 2 | epoch) */
+    __le32  i_mtime_extra;  /* extra Modification time(nsec << 2 | epoch) */
+    __le32  i_atime_extra;  /* extra Access time      (nsec << 2 | epoch) */
+    __le32  i_crtime;       /* File Creation time */
+    __le32  i_crtime_extra; /* extra FileCreationtime (nsec << 2 | epoch) */
+    __le32  i_version_hi;      /* high 32 bits for 64-bit version */
+};
+
+#define i_disk_version osd1.linux1.l_i_version
+
+#if defined(__KERNEL__) || defined(__linux__)
+#define i_reserved1    osd1.linux1.l_i_reserved1
+#define i_file_acl_high        osd2.linux2.l_i_file_acl_high
+#define i_blocks_high  osd2.linux2.l_i_blocks_high
+#define i_uid_low      i_uid
+#define i_gid_low      i_gid
+#define i_uid_high     osd2.linux2.l_i_uid_high
+#define i_gid_high     osd2.linux2.l_i_gid_high
+#define i_reserved2    osd2.linux2.l_i_reserved2
+#endif
+/*
+ * File system states
+ */
+#define        EXT3_VALID_FS                   0x0001  /* Unmounted cleanly */
+#define        EXT3_ERROR_FS                   0x0002  /* Errors detected */
+#define        EXT3_ORPHAN_FS                  0x0004  /* Orphans being recovered */
+
+/*
+ * Mount flags
+ */
+#define EXT3_MOUNT_CHECK               0x00001 /* Do mount-time checks */
+#define EXT3_MOUNT_OLDALLOC            0x00002  /* Don't use the new Orlov allocator */
+#define EXT3_MOUNT_GRPID               0x00004 /* Create files with directory's group */
+#define EXT3_MOUNT_DEBUG               0x00008 /* Some debugging messages */
+#define EXT3_MOUNT_ERRORS_CONT         0x00010 /* Continue on errors */
+#define EXT3_MOUNT_ERRORS_RO           0x00020 /* Remount fs ro on errors */
+#define EXT3_MOUNT_ERRORS_PANIC                0x00040 /* Panic on errors */
+#define EXT3_MOUNT_MINIX_DF            0x00080 /* Mimics the Minix statfs */
+#define EXT3_MOUNT_NOLOAD              0x00100 /* Don't use existing journal*/
+#define EXT3_MOUNT_ABORT               0x00200 /* Fatal error detected */
+#define EXT3_MOUNT_DATA_FLAGS          0x00C00 /* Mode for data writes: */
+#define EXT3_MOUNT_JOURNAL_DATA                0x00400 /* Write data to journal */
+#define EXT3_MOUNT_ORDERED_DATA                0x00800 /* Flush data before commit */
+#define EXT3_MOUNT_WRITEBACK_DATA      0x00C00 /* No data ordering */
+#define EXT3_MOUNT_UPDATE_JOURNAL      0x01000 /* Update the journal format */
+#define EXT3_MOUNT_NO_UID32            0x02000  /* Disable 32-bit UIDs */
+#define EXT3_MOUNT_XATTR_USER          0x04000 /* Extended user attributes */
+#define EXT3_MOUNT_POSIX_ACL           0x08000 /* POSIX Access Control Lists */
+#define EXT3_MOUNT_RESERVATION         0x10000 /* Preallocation */
+#define EXT3_MOUNT_BARRIER             0x20000 /* Use block barriers */
+#define EXT3_MOUNT_NOBH                        0x40000 /* No bufferheads */
+#define EXT3_MOUNT_QUOTA               0x80000 /* Some quota option set */
+#define EXT3_MOUNT_USRQUOTA            0x100000 /* "old" user quota */
+#define EXT3_MOUNT_GRPQUOTA            0x200000 /* "old" group quota */
+
+/* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */
+#ifndef _LINUX_EXT2_FS_H
+#define clear_opt(o, opt)              o &= ~EXT3_MOUNT_##opt
+#define set_opt(o, opt)                        o |= EXT3_MOUNT_##opt
+#define test_opt(sb, opt)              (EXT3_SB(sb)->s_mount_opt & \
+                                        EXT3_MOUNT_##opt)
+#else
+#define EXT2_MOUNT_NOLOAD              EXT3_MOUNT_NOLOAD
+#define EXT2_MOUNT_ABORT               EXT3_MOUNT_ABORT
+#define EXT2_MOUNT_DATA_FLAGS          EXT3_MOUNT_DATA_FLAGS
+#endif
+
+#define ext3_set_bit                   ext2_set_bit
+#define ext3_set_bit_atomic            ext2_set_bit_atomic
+#define ext3_clear_bit                 ext2_clear_bit
+#define ext3_clear_bit_atomic          ext2_clear_bit_atomic
+#define ext3_test_bit                  ext2_test_bit
+#define ext3_find_first_zero_bit       ext2_find_first_zero_bit
+#define ext3_find_next_zero_bit                ext2_find_next_zero_bit
+
+/*
+ * Maximal mount counts between two filesystem checks
+ */
+#define EXT3_DFL_MAX_MNT_COUNT         20      /* Allow 20 mounts */
+#define EXT3_DFL_CHECKINTERVAL         0       /* Don't use interval check */
+
+/*
+ * Behaviour when detecting errors
+ */
+#define EXT3_ERRORS_CONTINUE           1       /* Continue execution */
+#define EXT3_ERRORS_RO                 2       /* Remount fs read-only */
+#define EXT3_ERRORS_PANIC              3       /* Panic */
+#define EXT3_ERRORS_DEFAULT            EXT3_ERRORS_CONTINUE
+
+/*
+ * Structure of the super block
+ */
+struct ext3_super_block {
+    /*00*/
+    __le32     s_inodes_count;         /* Inodes count */
+    __le32     s_blocks_count; /* Blocks count */
+    __le32     s_r_blocks_count;       /* Reserved blocks count */
+    __le32     s_free_blocks_count;    /* Free blocks count */
+    /*10*/
+    __le32     s_free_inodes_count;    /* Free inodes count */
+    __le32     s_first_data_block;     /* First Data Block */
+    __le32     s_log_block_size;       /* Block size */
+    __le32     s_obso_log_frag_size;   /* Obsoleted fragment size */
+    /*20*/
+    __le32     s_blocks_per_group;     /* # Blocks per group */
+    __le32     s_obso_frags_per_group; /* Obsoleted fragments per group */
+    __le32     s_inodes_per_group;     /* # Inodes per group */
+    __le32     s_mtime;                /* Mount time */
+    /*30*/
+    __le32     s_wtime;                /* Write time */
+    __le16     s_mnt_count;            /* Mount count */
+    __le16     s_max_mnt_count;        /* Maximal mount count */
+    __le16     s_magic;                /* Magic signature */
+    __le16     s_state;                /* File system state */
+    __le16     s_errors;               /* Behaviour when detecting errors */
+    __le16     s_minor_rev_level;      /* minor revision level */
+    /*40*/
+    __le32     s_lastcheck;            /* time of last check */
+    __le32     s_checkinterval;        /* max. time between checks */
+    __le32     s_creator_os;           /* OS */
+    __le32     s_rev_level;            /* Revision level */
+    /*50*/
+    __le16     s_def_resuid;           /* Default uid for reserved blocks */
+    __le16     s_def_resgid;           /* Default gid for reserved blocks */
+    /*
+     * These fields are for EXT4_DYNAMIC_REV superblocks only.
+     *
+     * Note: the difference between the compatible feature set and
+     * the incompatible feature set is that if there is a bit set
+     * in the incompatible feature set that the kernel doesn't
+     * know about, it should refuse to mount the filesystem.
+     *
+     * e2fsck's requirements are more strict; if it doesn't know
+     * about a feature in either the compatible or incompatible
+     * feature set, it must abort and not try to meddle with
+     * things it doesn't understand...
+     */
+    __le32     s_first_ino;            /* First non-reserved inode */
+    __le16  s_inode_size;              /* size of inode structure */
+    __le16     s_block_group_nr;       /* block group # of this superblock */
+    __le32     s_feature_compat;       /* compatible feature set */
+    /*60*/
+    __le32     s_feature_incompat;     /* incompatible feature set */
+    __le32     s_feature_ro_compat;    /* readonly-compatible feature set */
+    /*68*/
+    __u8       s_uuid[16];             /* 128-bit uuid for volume */
+    /*78*/
+    char       s_volume_name[16];      /* volume name */
+    /*88*/
+    char       s_last_mounted[64];     /* directory where last mounted */
+    /*C8*/
+    __le32     s_algorithm_usage_bitmap; /* For compression */
+    /*
+     * Performance hints.  Directory preallocation should only
+     * happen if the EXT4_FEATURE_COMPAT_DIR_PREALLOC flag is on.
+     */
+    __u8       s_prealloc_blocks;      /* Nr of blocks to try to preallocate*/
+    __u8       s_prealloc_dir_blocks;  /* Nr to preallocate for dirs */
+    __le16     s_reserved_gdt_blocks;  /* Per group desc for online growth */
+    /*
+     * Journaling support valid if EXT4_FEATURE_COMPAT_HAS_JOURNAL set.
+     */
+    /*D0*/
+    __u8       s_journal_uuid[16];     /* uuid of journal superblock */
+    /*E0*/
+    __le32     s_journal_inum;         /* inode number of journal file */
+    __le32     s_journal_dev;          /* device number of journal file */
+    __le32     s_last_orphan;          /* start of list of inodes to delete */
+    __le32     s_hash_seed[4];         /* HTREE hash seed */
+    __u8       s_def_hash_version;     /* Default hash version to use */
+    __u8       s_reserved_char_pad;
+    __le16  s_desc_size;               /* size of group descriptor */
+    /*100*/
+    __le32     s_default_mount_opts;
+    __le32     s_first_meta_bg;        /* First metablock block group */
+    __le32     s_mkfs_time;            /* When the filesystem was created */
+    __le32     s_jnl_blocks[17];       /* Backup of the journal inode */
+    /* 64bit support valid if EXT4_FEATURE_COMPAT_64BIT */
+    /*150*/
+    __le32     s_blocks_count_hi;      /* Blocks count */
+    __le32     s_r_blocks_count_hi;    /* Reserved blocks count */
+    __le32     s_free_blocks_count_hi; /* Free blocks count */
+    __le16     s_min_extra_isize;      /* All inodes have at least # bytes */
+    __le16     s_want_extra_isize;     /* New inodes should reserve # bytes */
+    __le32     s_flags;                /* Miscellaneous flags */
+    __le16  s_raid_stride;             /* RAID stride */
+    __le16  s_mmp_interval;         /* # seconds to wait in MMP checking */
+    __le64  s_mmp_block;            /* Block for multi-mount protection */
+    __le32  s_raid_stripe_width;    /* blocks on all data disks (N*stride)*/
+    __u8       s_log_groups_per_flex;  /* FLEX_BG group size */
+    __u8       s_reserved_char_pad2;
+    __le16  s_reserved_pad;
+    __u32   s_reserved[162];        /* Padding to the end of the block */
+};
+
+#ifdef __KERNEL__
+#include <linux/ext3_fs_i.h>
+#include <linux/ext3_fs_sb.h>
+static inline struct ext3_sb_info * EXT3_SB(struct super_block *sb)
+{
+    return sb->s_fs_info;
+}
+static inline struct inode *EXT3_I(struct inode *inode)
+{
+    return inode;
+}
+
+static inline int ext3_valid_inum(struct super_block *sb, unsigned long ino)
+{
+    return ino == EXT3_ROOT_INO ||
+           ino == EXT3_JOURNAL_INO ||
+           ino == EXT3_RESIZE_INO ||
+           (ino >= EXT3_FIRST_INO(sb) &&
+            ino <= le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count));
+}
+#else
+/* Assume that user mode programs are passing in an ext3fs superblock, not
+ * a kernel struct super_block.  This will allow us to call the feature-test
+ * macros from user land. */
+#define EXT3_SB(sb)    (sb)
+#endif
+
+
+#define NEXT_ORPHAN(inode) EXT3_I(inode)->i_dtime
+
+/*
+ * Codes for operating systems
+ */
+#define EXT3_OS_LINUX          0
+#define EXT3_OS_HURD           1
+#define EXT3_OS_MASIX          2
+#define EXT3_OS_FREEBSD                3
+#define EXT3_OS_LITES          4
+
+/*
+ * Revision levels
+ */
+#define EXT3_GOOD_OLD_REV      0       /* The good old (original) format */
+#define EXT3_DYNAMIC_REV       1       /* V2 format w/ dynamic inode sizes */
+
+#define EXT3_CURRENT_REV       EXT3_GOOD_OLD_REV
+#define EXT3_MAX_SUPP_REV      EXT3_DYNAMIC_REV
+
+#define EXT3_GOOD_OLD_INODE_SIZE 128
+
+/*
+ * Feature set definitions
+ */
+
+#define EXT3_HAS_COMPAT_FEATURE(sb,mask)                       \
+       ( EXT3_SB(sb)->s_es->s_feature_compat & cpu_to_le32(mask) )
+#define EXT3_HAS_RO_COMPAT_FEATURE(sb,mask)                    \
+       ( EXT3_SB(sb)->s_es->s_feature_ro_compat & cpu_to_le32(mask) )
+#define EXT3_HAS_INCOMPAT_FEATURE(sb,mask)                     \
+       ( EXT3_SB(sb)->s_es->s_feature_incompat & cpu_to_le32(mask) )
+#define EXT3_SET_COMPAT_FEATURE(sb,mask)                       \
+       EXT3_SB(sb)->s_es->s_feature_compat |= cpu_to_le32(mask)
+#define EXT3_SET_RO_COMPAT_FEATURE(sb,mask)                    \
+       EXT3_SB(sb)->s_es->s_feature_ro_compat |= cpu_to_le32(mask)
+#define EXT3_SET_INCOMPAT_FEATURE(sb,mask)                     \
+       EXT3_SB(sb)->s_es->s_feature_incompat |= cpu_to_le32(mask)
+#define EXT3_CLEAR_COMPAT_FEATURE(sb,mask)                     \
+       EXT3_SB(sb)->s_es->s_feature_compat &= ~cpu_to_le32(mask)
+#define EXT3_CLEAR_RO_COMPAT_FEATURE(sb,mask)                  \
+       EXT3_SB(sb)->s_es->s_feature_ro_compat &= ~cpu_to_le32(mask)
+#define EXT3_CLEAR_INCOMPAT_FEATURE(sb,mask)                   \
+       EXT3_SB(sb)->s_es->s_feature_incompat &= ~cpu_to_le32(mask)
+
+#define EXT3_FEATURE_COMPAT_DIR_PREALLOC       0x0001
+#define EXT3_FEATURE_COMPAT_IMAGIC_INODES      0x0002
+#define EXT3_FEATURE_COMPAT_HAS_JOURNAL                0x0004
+#define EXT3_FEATURE_COMPAT_EXT_ATTR           0x0008
+#define EXT3_FEATURE_COMPAT_RESIZE_INODE       0x0010
+#define EXT3_FEATURE_COMPAT_DIR_INDEX          0x0020
+
+#define EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER    0x0001
+#define EXT3_FEATURE_RO_COMPAT_LARGE_FILE      0x0002
+#define EXT3_FEATURE_RO_COMPAT_BTREE_DIR       0x0004
+#define EXT4_FEATURE_RO_COMPAT_GDT_CSUM                0x0010
+#define EXT4_FEATURE_RO_COMPAT_DIR_NLINK       0x0020
+#define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE     0x0040
+
+#define EXT3_FEATURE_INCOMPAT_COMPRESSION      0x0001
+#define EXT3_FEATURE_INCOMPAT_FILETYPE         0x0002
+#define EXT3_FEATURE_INCOMPAT_RECOVER          0x0004 /* Needs recovery */
+#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV      0x0008 /* Journal device */
+#define EXT3_FEATURE_INCOMPAT_META_BG          0x0010
+#define EXT3_FEATURE_INCOMPAT_EXTENTS          0x0040 /* extents support */
+#define EXT3_FEATURE_INCOMPAT_MMP           0x0100
+#define EXT3_FEATURE_INCOMPAT_DIRDATA          0x1000
+
+#define EXT3_FEATURE_COMPAT_SUPP       EXT2_FEATURE_COMPAT_EXT_ATTR
+
+#define EXT4_FEATURE_COMPAT_DIR_PREALLOC       0x0001
+#define EXT4_FEATURE_COMPAT_IMAGIC_INODES      0x0002
+#define EXT4_FEATURE_COMPAT_HAS_JOURNAL                0x0004
+#define EXT4_FEATURE_COMPAT_EXT_ATTR           0x0008
+#define EXT4_FEATURE_COMPAT_RESIZE_INODE       0x0010
+#define EXT4_FEATURE_COMPAT_DIR_INDEX          0x0020
+
+#define EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER    0x0001
+#define EXT4_FEATURE_RO_COMPAT_LARGE_FILE      0x0002
+#define EXT4_FEATURE_RO_COMPAT_BTREE_DIR       0x0004
+#define EXT4_FEATURE_RO_COMPAT_HUGE_FILE    0x0008
+#define EXT4_FEATURE_RO_COMPAT_GDT_CSUM                0x0010
+#define EXT4_FEATURE_RO_COMPAT_DIR_NLINK       0x0020
+#define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE     0x0040
+
+#define EXT4_FEATURE_INCOMPAT_COMPRESSION      0x0001
+#define EXT4_FEATURE_INCOMPAT_FILETYPE         0x0002
+#define EXT4_FEATURE_INCOMPAT_RECOVER          0x0004 /* Needs recovery */
+#define EXT4_FEATURE_INCOMPAT_JOURNAL_DEV      0x0008 /* Journal device */
+#define EXT4_FEATURE_INCOMPAT_META_BG          0x0010
+#define EXT4_FEATURE_INCOMPAT_EXTENTS          0x0040 /* extents support */
+#define EXT4_FEATURE_INCOMPAT_64BIT         0x0080
+#define EXT4_FEATURE_INCOMPAT_MMP           0x0100
+#define EXT4_FEATURE_INCOMPAT_FLEX_BG          0x0200
+#define EXT4_FEATURE_INCOMPAT_DIRDATA          0x1000  /* used by Lustre - ldiskfs */
+#define EXT4_FEATURE_INCOMPAT_BG_USE_META_CSUM 0x2000 /* use crc32c for bg */
+#define EXT4_FEATURE_INCOMPAT_LARGEDIR         0x4000 /* >2GB or 3-lvl htree */
+#define EXT4_FEATURE_INCOMPAT_INLINEDATA       0x8000 /* data in inode */
+
+#define EXT4_FEATURE_INCOMPAT_SUPP     (                       \
+                    EXT4_FEATURE_INCOMPAT_FILETYPE|         \
+                                       EXT4_FEATURE_INCOMPAT_RECOVER|          \
+                                       EXT4_FEATURE_INCOMPAT_META_BG|          \
+                                       EXT4_FEATURE_INCOMPAT_EXTENTS|          \
+                                       EXT4_FEATURE_INCOMPAT_64BIT|            \
+                                       EXT4_FEATURE_INCOMPAT_FLEX_BG)
+#define EXT4_FEATURE_RO_COMPAT_SUPP    (                       \
+                    EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER|    \
+                                       EXT4_FEATURE_RO_COMPAT_LARGE_FILE|      \
+                                       EXT4_FEATURE_RO_COMPAT_GDT_CSUM|        \
+                                       EXT4_FEATURE_RO_COMPAT_DIR_NLINK |      \
+                                       EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE |    \
+                                       EXT4_FEATURE_RO_COMPAT_BTREE_DIR |      \
+                                       EXT4_FEATURE_RO_COMPAT_HUGE_FILE)
+
+#define EXT4_BG_INODE_UNINIT   0x0001 /* Inode table/bitmap not in use */
+#define EXT4_BG_BLOCK_UNINIT   0x0002 /* Block bitmap not in use */
+#define EXT4_BG_INODE_ZEROED   0x0004 /* On-disk itable initialized to zero */
+
+/*
+ * Default values for user and/or group using reserved blocks
+ */
+#define        EXT3_DEF_RESUID         0
+#define        EXT3_DEF_RESGID         0
+
+/*
+ * Default mount options
+ */
+#define EXT3_DEFM_DEBUG                0x0001
+#define EXT3_DEFM_BSDGROUPS    0x0002
+#define EXT3_DEFM_XATTR_USER   0x0004
+#define EXT3_DEFM_ACL          0x0008
+#define EXT3_DEFM_UID16                0x0010
+#define EXT3_DEFM_JMODE                0x0060
+#define EXT3_DEFM_JMODE_DATA   0x0020
+#define EXT3_DEFM_JMODE_ORDERED        0x0040
+#define EXT3_DEFM_JMODE_WBACK  0x0060
+
+/*
+ * Structure of a directory entry
+ */
+#define EXT3_NAME_LEN 255
+
+struct ext3_dir_entry {
+    __le32     inode;                  /* Inode number */
+    __le16     rec_len;                /* Directory entry length */
+    __le16     name_len;               /* Name length */
+    char       name[EXT3_NAME_LEN];    /* File name */
+};
+
+/*
+ * The new version of the directory entry.  Since EXT3 structures are
+ * stored in intel byte order, and the name_len field could never be
+ * bigger than 255 chars, it's safe to reclaim the extra byte for the
+ * file_type field.
+ */
+struct ext3_dir_entry_2 {
+    __le32     inode;                  /* Inode number */
+    __le16     rec_len;                /* Directory entry length */
+    __u8       name_len;               /* Name length */
+    __u8       file_type;
+    char       name[EXT3_NAME_LEN];    /* File name */
+};
+
+/*
+ * Ext3 directory file types.  Only the low 3 bits are used.  The
+ * other bits are reserved for now.
+ */
+#define EXT3_FT_UNKNOWN                0
+#define EXT3_FT_REG_FILE       1
+#define EXT3_FT_DIR            2
+#define EXT3_FT_CHRDEV         3
+#define EXT3_FT_BLKDEV         4
+#define EXT3_FT_FIFO           5
+#define EXT3_FT_SOCK           6
+#define EXT3_FT_SYMLINK                7
+
+#define EXT3_FT_MAX            8
+#define EXT3_FT_MASK           0xf
+
+#if EXT3_FT_MAX > EXT3_FT_MASK
+#error "conflicting EXT3_FT_MAX and EXT3_FT_MASK"
+#endif
+
+#define EXT3_LUFID_MAGIC    0xAD200907UL
+
+#pragma pack(1)
+struct ext3_dentry_param {
+    __u32  edp_magic;       /* EXT3_LUFID_MAGIC */
+    char   edp_len;         /* size of edp_data in bytes */
+    char   edp_data[0];     /* packed array of data */
+} __attribute__((packed));
+#pragma pack()
+
+static inline unsigned char *ext3_dentry_get_data(struct super_block *sb,
+        struct ext3_dentry_param* p)
+
+{
+    if (!EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_DIRDATA))
+        return NULL;
+    if (p && p->edp_magic == EXT3_LUFID_MAGIC)
+        return &p->edp_len;
+    else
+        return NULL;
+}
+
+/*
+ * Compute the total directory entry data length.
+ * This includes the filename and an implicit NUL terminator (always present),
+ * and optional extensions.  Each extension has a bit set in the high 4 bits of
+ * de->file_type, and the extension length is the first byte in each entry.
+ */
+
+static inline int ext3_get_dirent_data_len(struct ext3_dir_entry_2 *de)
+{
+    char *len = de->name + de->name_len + 1 /* NUL terminator */;
+    int dlen = 0;
+    __u8 extra_data_flags = (de->file_type & ~EXT3_FT_MASK) >> 4;
+
+    while (extra_data_flags) {
+        if (extra_data_flags & 1) {
+            dlen += *len + (dlen == 0);
+            len += *len;
+        }
+        extra_data_flags >>= 1;
+    }
+    return dlen;
+}
+
+/*
+ * d_type has 4 unused bits, so it can hold four types data. these different
+ * type of data (e.g. lustre data, high 32 bits of 64-bit inode number) can be
+ * stored, in flag order, after file-name in ext3 dirent.
+*/
+/*
+ * this flag is added to d_type if ext3 dirent has extra data after
+ * filename. this data length is variable and length is stored in first byte
+ * of data. data start after filename NUL byte.
+ * This is used by Lustre FS.
+ */
+
+#define EXT3_DIRENT_LUFID              0x10
+/*
+ * EXT3_DIR_PAD defines the directory entries boundaries
+ *
+ * NOTE: It must be a multiple of 4
+ */
+#define EXT3_DIR_PAD                   4
+#define EXT3_DIR_ROUND                 (EXT3_DIR_PAD - 1)
+#define EXT3_DIR_REC_LEN(len)   (((len) + 8 + EXT3_DIR_ROUND) & \
+                                 ~EXT3_DIR_ROUND)
+#define EXT3_MAX_REC_LEN               ((1<<16)-1)
+
+static inline unsigned ext3_rec_len_from_disk(__le16 dlen)
+{
+    unsigned len = le16_to_cpu(dlen);
+
+    if (len == EXT3_MAX_REC_LEN || len == 0)
+        return 1 << 16;
+    return len;
+}
+
+static inline __le16 ext3_rec_len_to_disk(unsigned len)
+{
+    if (len == (1 << 16))
+        return cpu_to_le16(EXT3_MAX_REC_LEN);
+    else if (len > (1 << 16))
+        BUG();
+    return cpu_to_le16(len);
+}
+
+/*
+ * Hash Tree Directory indexing
+ * (c) Daniel Phillips, 2001
+ */
+
+#ifdef EXT2_HTREE_INDEX
+#define is_dx(dir) (EXT3_HAS_COMPAT_FEATURE(dir->i_sb, \
+                                             EXT3_FEATURE_COMPAT_DIR_INDEX) && \
+                     (EXT3_I(dir)->i_flags & EXT3_INDEX_FL))
+#define EXT3_DIR_LINK_MAX(dir) (!is_dx(dir) && (dir)->i_nlink >= EXT3_LINK_MAX)
+#define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2 || (dir)->i_nlink == 1)
+#else
+#define is_dx(dir) 0
+#define EXT3_DIR_LINK_MAX(dir) ((dir)->i_nlink >= EXT3_LINK_MAX)
+#define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2)
+#endif
+
+/* Legal values for the dx_root hash_version field: */
+
+#define DX_HASH_LEGACY              0
+#define DX_HASH_HALF_MD4            1
+#define DX_HASH_TEA                 2
+#define DX_HASH_LEGACY_UNSIGNED     3
+#define DX_HASH_HALF_MD4_UNSIGNED   4
+#define DX_HASH_TEA_UNSIGNED        5
+
+
+#ifdef __KERNEL__
+
+/* hash info structure used by the directory hash */
+struct dx_hash_info
+{
+    u32                hash;
+    u32                minor_hash;
+    int                hash_version;
+    u32                *seed;
+};
+
+#define EXT3_HTREE_EOF 0x7fffffff
+
+/* 32 and 64 bit signed EOF for dx directories */
+#define EXT4_HTREE_EOF_32BIT   ((1UL  << (32 - 1)) - 1)
+#define EXT4_HTREE_EOF_64BIT   ((1ULL << (64 - 1)) - 1
+
+/*
+ * Control parameters used by ext3_htree_next_block
+ */
+#define HASH_NB_ALWAYS         1
+
+
+/*
+ * Describe an inode's exact location on disk and in memory
+ */
+struct ext3_iloc
+{
+    struct buffer_head *bh;
+    unsigned long offset;
+    unsigned long block_group;
+};
+
+static inline struct ext3_inode *ext3_raw_inode(struct ext3_iloc *iloc)
+{
+    return (struct ext3_inode *) (iloc->bh->b_data + iloc->offset);
+}
+
+/*
+ * This structure is stuffed into the struct file's private_data field
+ * for directories.  It is where we put information so that we can do
+ * readdir operations in hash tree order.
+ */
+struct dir_private_info {
+    struct rb_root     root;
+    struct rb_node     *curr_node;
+    struct fname       *extra_fname;
+    loff_t             last_pos;
+    __u32              curr_hash;
+    __u32              curr_minor_hash;
+    __u32              next_hash;
+};
+
+/* calculate the first block number of the group */
+static inline ext3_fsblk_t
+ext3_group_first_block_no(struct super_block *sb, unsigned long group_no)
+{
+    return group_no * (ext3_fsblk_t)EXT3_BLOCKS_PER_GROUP(sb) +
+           le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block);
+}
+
+/*
+ * Special error return code only used by dx_probe() and its callers.
+ */
+#define ERR_BAD_DX_DIR -75000
+
+/*
+ * This structure will be used for multiple mount protection. It will be
+ * written into the block number saved in the s_mmp_block field in the
+ * superblock. Programs that check MMP should assume that if
+ * SEQ_FSCK (or any unknown code above SEQ_MAX) is present then it is NOT safe
+ * to use the filesystem, regardless of how old the timestamp is.
+ */
+#define EXT3_MMP_MAGIC     0x004D4D50U /* ASCII for MMP */
+#define EXT3_MMP_SEQ_CLEAN 0xFF4D4D50U /* mmp_seq value for clean unmount */
+#define EXT3_MMP_SEQ_FSCK  0xE24D4D50U /* mmp_seq value when being fscked */
+#define EXT3_MMP_SEQ_MAX   0xE24D4D4FU /* maximum valid mmp_seq value */
+
+struct mmp_struct {
+    __le32     mmp_magic;
+    __le32     mmp_seq;
+    __le64     mmp_time;
+    char       mmp_nodename[64];
+    char       mmp_bdevname[32];
+    __le16     mmp_check_interval;
+    __le16     mmp_pad1;
+    __le32     mmp_pad2[227];
+};
+
+/*
+ * Default interval in seconds to update the MMP sequence number.
+ */
+#define EXT3_MMP_UPDATE_INTERVAL   1
+
+/*
+ * Minimum interval for MMP checking in seconds.
+ */
+#define EXT3_MMP_MIN_CHECK_INTERVAL    5
+
+/*
+ * Indicates that ctime should not be updated in ext3_xattr_set_handle()
+ */
+#ifndef XATTR_NO_CTIME
+#define XATTR_NO_CTIME 0x80
+#endif
+
+/*
+ * NOTE! unlike strncmp, ext3_match returns 1 for success, 0 for failure.
+ *
+ * `len <= EXT3_NAME_LEN' is guaranteed by caller.
+ * `de != NULL' is guaranteed by caller.
+ */
+static inline int ext3_match (int len, const char * const name,
+                              struct ext3_dir_entry_2 * de)
+{
+    if (len != de->name_len)
+        return 0;
+    if (!de->inode)
+        return 0;
+    return !_strnicmp(name, de->name, len);
+}
+
+#endif /* __KERNEL__ */
+#endif /* _LINUX_EXT3_FS_H */
diff --git a/reactos/drivers/filesystems/ext2_new/inc/linux/ext3_fs_i.h b/reactos/drivers/filesystems/ext2_new/inc/linux/ext3_fs_i.h
new file mode 100644 (file)
index 0000000..089d557
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ *  linux/include/linux/ext3_fs_i.h
+ *
+ * Copyright (C) 1992, 1993, 1994, 1995
+ * Remy Card (card@masi.ibp.fr)
+ * Laboratoire MASI - Institut Blaise Pascal
+ * Universite Pierre et Marie Curie (Paris VI)
+ *
+ *  from
+ *
+ *  linux/include/linux/minix_fs_i.h
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ */
+
+#ifndef _LINUX_EXT3_FS_I
+#define _LINUX_EXT3_FS_I
+
+#include <linux/rbtree.h>
+
+/* data type for block offset of block group */
+typedef int ext3_grpblk_t;
+typedef int ext4_grpblk_t;
+
+/* data type for filesystem-wide blocks number */
+typedef unsigned long long ext3_fsblk_t;
+typedef unsigned long long ext4_fsblk_t;
+
+/* data type for file logical block number */
+typedef __u32 ext3_lblk_t;
+typedef __u32 ext4_lblk_t;
+
+/* data type for block group number */
+typedef unsigned int ext3_group_t;
+typedef unsigned int ext4_group_t;
+
+#define E3FSBLK "%lu"
+
+struct ext3_reserve_window {
+    ext3_fsblk_t       _rsv_start;     /* First byte reserved */
+    ext3_fsblk_t       _rsv_end;       /* Last byte reserved or 0 */
+};
+
+struct ext3_reserve_window_node {
+    struct rb_node             rsv_node;
+    __u32                      rsv_goal_size;
+    __u32                      rsv_alloc_hit;
+    struct ext3_reserve_window rsv_window;
+};
+
+struct ext3_block_alloc_info {
+    /* information about reservation window */
+    struct ext3_reserve_window_node    rsv_window_node;
+    /*
+     * was i_next_alloc_block in ext3_inode_info
+     * is the logical (file-relative) number of the
+     * most-recently-allocated block in this file.
+     * We use this for detecting linearly ascending allocation requests.
+     */
+    __u32                   last_alloc_logical_block;
+    /*
+     * Was i_next_alloc_goal in ext3_inode_info
+     * is the *physical* companion to i_next_alloc_block.
+     * it the physical block number of the block which was most-recentl
+     * allocated to this file.  This give us the goal (target) for the next
+     * allocation when we detect linearly ascending requests.
+     */
+    ext3_fsblk_t               last_alloc_physical_block;
+};
+
+#define rsv_start rsv_window._rsv_start
+#define rsv_end rsv_window._rsv_end
+
+/*
+ * third extended file system inode data in memory
+ */
+struct ext3_inode_info {
+    __le32     i_data[15];     /* unconverted */
+    __u32      i_flags;
+#ifdef EXT3_FRAGMENTS
+    __u32      i_faddr;
+    __u8       i_frag_no;
+    __u8       i_frag_size;
+#endif
+    ext3_fsblk_t       i_file_acl;
+    __u32      i_dir_acl;
+    __u32      i_dtime;
+
+    /*
+     * i_block_group is the number of the block group which contains
+     * this file's inode.  Constant across the lifetime of the inode,
+     * it is ued for making block allocation decisions - we try to
+     * place a file's data blocks near its inode block, and new inodes
+     * near to their parent directory's inode.
+     */
+    __u32      i_block_group;
+    __u32      i_state;                /* Dynamic state flags for ext3 */
+
+    /* block reservation info */
+    struct ext3_block_alloc_info *i_block_alloc_info;
+
+    __u32      i_dir_start_lookup;
+#ifdef CONFIG_EXT3_FS_XATTR
+    /*
+     * Extended attributes can be read independently of the main file
+     * data. Taking i_mutex even when reading would cause contention
+     * between readers of EAs and writers of regular file data, so
+     * instead we synchronize on xattr_sem when reading or changing
+     * EAs.
+     */
+    struct rw_semaphore xattr_sem;
+#endif
+#ifdef CONFIG_EXT3_FS_POSIX_ACL
+    struct posix_acl   *i_acl;
+    struct posix_acl   *i_default_acl;
+#endif
+
+    struct list_head i_orphan; /* unlinked but open inodes */
+
+    /*
+     * i_disksize keeps track of what the inode size is ON DISK, not
+     * in memory.  During truncate, i_size is set to the new size by
+     * the VFS prior to calling ext3_truncate(), but the filesystem won't
+     * set i_disksize to 0 until the truncate is actually under way.
+     *
+     * The intent is that i_disksize always represents the blocks which
+     * are used by this file.  This allows recovery to restart truncate
+     * on orphans if we crash during truncate.  We actually write i_disksize
+     * into the on-disk inode when writing inodes out, instead of i_size.
+     *
+     * The only time when i_disksize and i_size may be different is when
+     * a truncate is in progress.  The only things which change i_disksize
+     * are ext3_get_block (growth) and ext3_truncate (shrinkth).
+     */
+    loff_t     i_disksize;
+
+    /* on-disk additional length */
+    __u16 i_extra_isize;
+
+#if 0
+    /*
+     * truncate_mutex is for serialising ext3_truncate() against
+     * ext3_getblock().  In the 2.4 ext2 design, great chunks of inode's
+     * data tree are chopped off during truncate. We can't do that in
+     * ext3 because whenever we perform intermediate commits during
+     * truncate, the inode and all the metadata blocks *must* be in a
+     * consistent state which allows truncation of the orphans to restart
+     * during recovery.  Hence we must fix the get_block-vs-truncate race
+     * by other means, so we have truncate_mutex.
+     */
+    struct mutex truncate_mutex;
+#endif
+    struct inode vfs_inode;
+};
+
+#endif /* _LINUX_EXT3_FS_I */
diff --git a/reactos/drivers/filesystems/ext2_new/inc/linux/ext3_fs_sb.h b/reactos/drivers/filesystems/ext2_new/inc/linux/ext3_fs_sb.h
new file mode 100644 (file)
index 0000000..201607e
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ *  linux/include/linux/ext3_fs_sb.h
+ *
+ * Copyright (C) 1992, 1993, 1994, 1995
+ * Remy Card (card@masi.ibp.fr)
+ * Laboratoire MASI - Institut Blaise Pascal
+ * Universite Pierre et Marie Curie (Paris VI)
+ *
+ *  from
+ *
+ *  linux/include/linux/minix_fs_sb.h
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ */
+
+#ifndef _LINUX_EXT3_FS_SB
+#define _LINUX_EXT3_FS_SB
+
+#include <linux/types.h>
+#include <linux/rbtree.h>
+
+/*
+ * third extended-fs super-block data in memory
+ */
+struct ext3_sb_info {
+
+    unsigned long s_desc_size;      /* size of group desc */
+    unsigned long s_gdb_count; /* Number of group descriptor blocks */
+    unsigned long s_desc_per_block;    /* Number of group descriptors per block */
+    unsigned long s_inodes_per_group;/* Number of inodes in a group */
+    unsigned long s_inodes_per_block;/* Number of inodes per block */
+    unsigned long s_blocks_per_group;/* Number of blocks in a group */
+    unsigned long s_groups_count;      /* Number of groups in the fs */
+    unsigned long s_itb_per_group;     /* Number of inode table blocks per group */
+
+    int s_addr_per_block_bits;
+    int s_desc_per_block_bits;
+
+    struct buffer_head **s_group_desc;
+
+#if 0
+    unsigned long s_frag_size; /* Size of a fragment in bytes */
+    unsigned long s_frags_per_block;/* Number of fragments per block */
+    unsigned long s_frags_per_group;/* Number of fragments in a group */
+    unsigned long s_inodes_per_group;/* Number of inodes in a group */
+    unsigned long s_itb_per_group;     /* Number of inode table blocks per group */
+    unsigned long s_desc_per_block;    /* Number of group descriptors per block */
+    unsigned long s_overhead_last;  /* Last calculated overhead */
+    unsigned long s_blocks_last;    /* Last seen block count */
+#endif
+
+    struct ext3_super_block * s_es;    /* Pointer to the super block in the buffer */
+
+    __le32 s_first_ino;
+
+    u32 s_hash_seed[4];
+    int s_def_hash_version;
+};
+
+int ext3_release_dir (struct inode * inode, struct file * filp);
+
+#endif /* _LINUX_EXT3_FS_SB */
diff --git a/reactos/drivers/filesystems/ext2_new/inc/linux/ext3_jbd.h b/reactos/drivers/filesystems/ext2_new/inc/linux/ext3_jbd.h
new file mode 100644 (file)
index 0000000..acee54f
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+ * linux/include/linux/ext3_jbd.h
+ *
+ * Written by Stephen C. Tweedie <sct@redhat.com>, 1999
+ *
+ * Copyright 1998--1999 Red Hat corp --- All Rights Reserved
+ *
+ * This file is part of the Linux kernel and is made available under
+ * the terms of the GNU General Public License, version 2, or at your
+ * option, any later version, incorporated herein by reference.
+ *
+ * Ext3-specific journaling extensions.
+ */
+
+#ifndef _LINUX_EXT3_JBD_H
+#define _LINUX_EXT3_JBD_H
+
+#include <linux/fs.h>
+#include <linux/jbd.h>
+#include <linux/ext3_fs.h>
+
+#define EXT3_JOURNAL(inode)    (EXT3_SB((inode)->i_sb)->s_journal)
+
+/* Define the number of blocks we need to account to a transaction to
+ * modify one block of data.
+ *
+ * We may have to touch one inode, one bitmap buffer, up to three
+ * indirection blocks, the group and superblock summaries, and the data
+ * block to complete the transaction.  */
+
+#define EXT3_SINGLEDATA_TRANS_BLOCKS   8U
+
+/* Extended attribute operations touch at most two data buffers,
+ * two bitmap buffers, and two group summaries, in addition to the inode
+ * and the superblock, which are already accounted for. */
+
+#define EXT3_XATTR_TRANS_BLOCKS                6U
+
+/* Define the minimum size for a transaction which modifies data.  This
+ * needs to take into account the fact that we may end up modifying two
+ * quota files too (one for the group, one for the user quota).  The
+ * superblock only gets updated once, of course, so don't bother
+ * counting that again for the quota updates. */
+
+#define EXT3_DATA_TRANS_BLOCKS(sb)     (EXT3_SINGLEDATA_TRANS_BLOCKS + \
+                                        EXT3_XATTR_TRANS_BLOCKS - 2 + \
+                                        2*EXT3_QUOTA_TRANS_BLOCKS(sb))
+
+/* Delete operations potentially hit one directory's namespace plus an
+ * entire inode, plus arbitrary amounts of bitmap/indirection data.  Be
+ * generous.  We can grow the delete transaction later if necessary. */
+
+#define EXT3_DELETE_TRANS_BLOCKS(sb)   (2 * EXT3_DATA_TRANS_BLOCKS(sb) + 64)
+
+/* Define an arbitrary limit for the amount of data we will anticipate
+ * writing to any given transaction.  For unbounded transactions such as
+ * write(2) and truncate(2) we can write more than this, but we always
+ * start off at the maximum transaction size and grow the transaction
+ * optimistically as we go. */
+
+#define EXT3_MAX_TRANS_DATA            64U
+
+/* We break up a large truncate or write transaction once the handle's
+ * buffer credits gets this low, we need either to extend the
+ * transaction or to start a new one.  Reserve enough space here for
+ * inode, bitmap, superblock, group and indirection updates for at least
+ * one block, plus two quota updates.  Quota allocations are not
+ * needed. */
+
+#define EXT3_RESERVE_TRANS_BLOCKS      12U
+
+#define EXT3_INDEX_EXTRA_TRANS_BLOCKS  8
+
+#ifdef CONFIG_QUOTA
+/* Amount of blocks needed for quota update - we know that the structure was
+ * allocated so we need to update only inode+data */
+#define EXT3_QUOTA_TRANS_BLOCKS(sb) (test_opt(sb, QUOTA) ? 2 : 0)
+/* Amount of blocks needed for quota insert/delete - we do some block writes
+ * but inode, sb and group updates are done only once */
+#define EXT3_QUOTA_INIT_BLOCKS(sb) (test_opt(sb, QUOTA) ? (DQUOT_INIT_ALLOC*\
+               (EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3+DQUOT_INIT_REWRITE) : 0)
+#define EXT3_QUOTA_DEL_BLOCKS(sb) (test_opt(sb, QUOTA) ? (DQUOT_DEL_ALLOC*\
+               (EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3+DQUOT_DEL_REWRITE) : 0)
+#else
+#define EXT3_QUOTA_TRANS_BLOCKS(sb) 0
+#define EXT3_QUOTA_INIT_BLOCKS(sb) 0
+#define EXT3_QUOTA_DEL_BLOCKS(sb) 0
+#endif
+
+int
+ext3_mark_iloc_dirty(handle_t *handle,
+                     struct inode *inode,
+                     struct ext3_iloc *iloc);
+
+/*
+ * On success, We end up with an outstanding reference count against
+ * iloc->bh.  This _must_ be cleaned up later.
+ */
+
+int ext3_reserve_inode_write(handle_t *handle, struct inode *inode,
+                             struct ext3_iloc *iloc);
+
+int ext3_mark_inode_dirty(handle_t *handle, struct inode *inode);
+
+/*
+ * Wrapper functions with which ext3 calls into JBD.  The intent here is
+ * to allow these to be turned into appropriate stubs so ext3 can control
+ * ext2 filesystems, so ext2+ext3 systems only nee one fs.  This work hasn't
+ * been done yet.
+ */
+
+static inline void ext3_journal_release_buffer(handle_t *handle,
+        struct buffer_head *bh)
+{
+    journal_release_buffer(handle, bh);
+}
+
+void ext3_journal_abort_handle(const char *caller, const char *err_fn,
+                               struct buffer_head *bh, handle_t *handle, int err);
+
+int __ext3_journal_get_undo_access(const char *where, handle_t *handle,
+                                   struct buffer_head *bh);
+
+int __ext3_journal_get_write_access(const char *where, handle_t *handle,
+                                    struct buffer_head *bh);
+
+int __ext3_journal_forget(const char *where, handle_t *handle,
+                          struct buffer_head *bh);
+
+int __ext3_journal_revoke(const char *where, handle_t *handle,
+                          unsigned long blocknr, struct buffer_head *bh);
+
+int __ext3_journal_get_create_access(const char *where,
+                                     handle_t *handle, struct buffer_head *bh);
+
+int __ext3_journal_dirty_metadata(const char *where,
+                                  handle_t *handle, struct buffer_head *bh);
+
+#define ext3_journal_get_undo_access(handle, bh) \
+       __ext3_journal_get_undo_access(__FUNCTION__, (handle), (bh))
+#define ext3_journal_get_write_access(handle, bh) \
+       __ext3_journal_get_write_access(__FUNCTION__, (handle), (bh))
+#define ext3_journal_revoke(handle, blocknr, bh) \
+       __ext3_journal_revoke(__FUNCTION__, (handle), (blocknr), (bh))
+#define ext3_journal_get_create_access(handle, bh) \
+       __ext3_journal_get_create_access(__FUNCTION__, (handle), (bh))
+#define ext3_journal_dirty_metadata(handle, bh) \
+       __ext3_journal_dirty_metadata(__FUNCTION__, (handle), (bh))
+#define ext3_journal_forget(handle, bh) \
+       __ext3_journal_forget(__FUNCTION__, (handle), (bh))
+
+int ext3_journal_dirty_data(handle_t *handle, struct buffer_head *bh);
+
+handle_t *ext3_journal_start_sb(struct super_block *sb, int nblocks);
+int __ext3_journal_stop(const char *where, handle_t *handle);
+
+static inline handle_t *ext3_journal_start(struct inode *inode, int nblocks)
+{
+    return ext3_journal_start_sb(inode->i_sb, nblocks);
+}
+
+#define ext3_journal_stop(handle) \
+       __ext3_journal_stop(__FUNCTION__, (handle))
+
+static inline handle_t *ext3_journal_current_handle(void)
+{
+    return journal_current_handle();
+}
+
+static inline int ext3_journal_extend(handle_t *handle, int nblocks)
+{
+    return journal_extend(handle, nblocks);
+}
+
+static inline int ext3_journal_restart(handle_t *handle, int nblocks)
+{
+    return journal_restart(handle, nblocks);
+}
+
+static inline int ext3_journal_blocks_per_page(struct inode *inode)
+{
+    return journal_blocks_per_page(inode);
+}
+
+static inline int ext3_journal_force_commit(journal_t *journal)
+{
+    return journal_force_commit(journal);
+}
+
+/* super.c */
+int ext3_force_commit(struct super_block *sb);
+
+static inline int ext3_should_journal_data(struct inode *inode)
+{
+    if (!S_ISREG(inode->i_mode))
+        return 1;
+    if (test_opt(inode->i_sb, DATA_FLAGS) == EXT3_MOUNT_JOURNAL_DATA)
+        return 1;
+    if (EXT3_I(inode)->i_flags & EXT3_JOURNAL_DATA_FL)
+        return 1;
+    return 0;
+}
+
+static inline int ext3_should_order_data(struct inode *inode)
+{
+    if (!S_ISREG(inode->i_mode))
+        return 0;
+    if (EXT3_I(inode)->i_flags & EXT3_JOURNAL_DATA_FL)
+        return 0;
+    if (test_opt(inode->i_sb, DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA)
+        return 1;
+    return 0;
+}
+
+static inline int ext3_should_writeback_data(struct inode *inode)
+{
+    if (!S_ISREG(inode->i_mode))
+        return 0;
+    if (EXT3_I(inode)->i_flags & EXT3_JOURNAL_DATA_FL)
+        return 0;
+    if (test_opt(inode->i_sb, DATA_FLAGS) == EXT3_MOUNT_WRITEBACK_DATA)
+        return 1;
+    return 0;
+}
+
+#endif /* _LINUX_EXT3_JBD_H */
diff --git a/reactos/drivers/filesystems/ext2_new/inc/linux/ext4.h b/reactos/drivers/filesystems/ext2_new/inc/linux/ext4.h
new file mode 100644 (file)
index 0000000..2aa4a39
--- /dev/null
@@ -0,0 +1,122 @@
+#ifndef _EXT4_H
+#define _EXT4_H
+
+#include <linux/jbd.h>
+/* Temporarily we need this. */
+#include <linux/ext3_fs.h>
+
+typedef unsigned __int16 uint16_t;
+typedef unsigned __int32 uint32_t;
+typedef unsigned __int64 uint64_t;
+
+typedef uint32_t ext4_lblk_t;
+typedef uint64_t ext4_fsblk_t;
+
+/*
+ * Flags used by ext4_map_blocks()
+ */
+       /* Allocate any needed blocks and/or convert an unwritten
+          extent to be an initialized ext4 */
+#define EXT4_GET_BLOCKS_CREATE                 0x0001
+       /* Request the creation of an unwritten extent */
+#define EXT4_GET_BLOCKS_UNWRIT_EXT             0x0002
+#define EXT4_GET_BLOCKS_CREATE_UNWRIT_EXT      (EXT4_GET_BLOCKS_UNWRIT_EXT|\
+                                                EXT4_GET_BLOCKS_CREATE)
+       /* Caller is from the delayed allocation writeout path
+        * finally doing the actual allocation of delayed blocks */
+#define EXT4_GET_BLOCKS_DELALLOC_RESERVE       0x0004
+       /* caller is from the direct IO path, request to creation of an
+       unwritten extents if not allocated, split the unwritten
+       extent if blocks has been preallocated already*/
+#define EXT4_GET_BLOCKS_PRE_IO                 0x0008
+#define EXT4_GET_BLOCKS_CONVERT                        0x0010
+#define EXT4_GET_BLOCKS_IO_CREATE_EXT          (EXT4_GET_BLOCKS_PRE_IO|\
+                                        EXT4_GET_BLOCKS_CREATE_UNWRIT_EXT)
+       /* Convert extent to initialized after IO complete */
+#define EXT4_GET_BLOCKS_IO_CONVERT_EXT         (EXT4_GET_BLOCKS_CONVERT|\
+                                        EXT4_GET_BLOCKS_CREATE_UNWRIT_EXT)
+       /* Eventual metadata allocation (due to growing extent tree)
+        * should not fail, so try to use reserved blocks for that.*/
+#define EXT4_GET_BLOCKS_METADATA_NOFAIL                0x0020
+       /* Don't normalize allocation size (used for fallocate) */
+#define EXT4_GET_BLOCKS_NO_NORMALIZE           0x0040
+       /* Request will not result in inode size update (user for fallocate) */
+#define EXT4_GET_BLOCKS_KEEP_SIZE              0x0080
+       /* Do not take i_data_sem locking in ext4_map_blocks */
+#define EXT4_GET_BLOCKS_NO_LOCK                        0x0100
+       /* Do not put hole in extent cache */
+#define EXT4_GET_BLOCKS_NO_PUT_HOLE            0x0200
+       /* Convert written extents to unwritten */
+#define EXT4_GET_BLOCKS_CONVERT_UNWRITTEN      0x0400
+
+/*
+ * The bit position of these flags must not overlap with any of the
+ * EXT4_GET_BLOCKS_*.  They are used by ext4_find_extent(),
+ * read_extent_tree_block(), ext4_split_extent_at(),
+ * ext4_ext_insert_extent(), and ext4_ext_create_new_leaf().
+ * EXT4_EX_NOCACHE is used to indicate that the we shouldn't be
+ * caching the extents when reading from the extent tree while a
+ * truncate or punch hole operation is in progress.
+ */
+#define EXT4_EX_NOCACHE                                0x40000000
+#define EXT4_EX_FORCE_CACHE                    0x20000000
+
+/*
+ * Flags used by ext4_free_blocks
+ */
+#define EXT4_FREE_BLOCKS_METADATA      0x0001
+#define EXT4_FREE_BLOCKS_FORGET                0x0002
+#define EXT4_FREE_BLOCKS_VALIDATED     0x0004
+#define EXT4_FREE_BLOCKS_NO_QUOT_UPDATE        0x0008
+#define EXT4_FREE_BLOCKS_NOFREE_FIRST_CLUSTER  0x0010
+#define EXT4_FREE_BLOCKS_NOFREE_LAST_CLUSTER   0x0020
+
+/*
+ * Flags used in mballoc's allocation_context flags field.
+ *
+ * Also used to show what's going on for debugging purposes when the
+ * flag field is exported via the traceport interface
+ */
+
+/* prefer goal again. length */
+#define EXT4_MB_HINT_MERGE             0x0001
+/* blocks already reserved */
+#define EXT4_MB_HINT_RESERVED          0x0002
+/* metadata is being allocated */
+#define EXT4_MB_HINT_METADATA          0x0004
+/* first blocks in the file */
+#define EXT4_MB_HINT_FIRST             0x0008
+/* search for the best chunk */
+#define EXT4_MB_HINT_BEST              0x0010
+/* data is being allocated */
+#define EXT4_MB_HINT_DATA              0x0020
+/* don't preallocate (for tails) */
+#define EXT4_MB_HINT_NOPREALLOC                0x0040
+/* allocate for locality group */
+#define EXT4_MB_HINT_GROUP_ALLOC       0x0080
+/* allocate goal blocks or none */
+#define EXT4_MB_HINT_GOAL_ONLY         0x0100
+/* goal is meaningful */
+#define EXT4_MB_HINT_TRY_GOAL          0x0200
+/* blocks already pre-reserved by delayed allocation */
+#define EXT4_MB_DELALLOC_RESERVED      0x0400
+/* We are doing stream allocation */
+#define EXT4_MB_STREAM_ALLOC           0x0800
+/* Use reserved root blocks if needed */
+#define EXT4_MB_USE_ROOT_BLOCKS                0x1000
+/* Use blocks from reserved pool */
+#define EXT4_MB_USE_RESERVED           0x2000
+
+
+#define ext4_sb_info ext3_sb_info
+
+static inline struct ext4_sb_info * EXT4_SB(struct super_block *sb)
+{
+    return sb->s_fs_info;
+}
+#define EXT4_I(i) (i)
+
+#include <linux/ext4_jbd2.h>
+#include <linux/ext4_ext.h>
+
+#endif /* _EXT4_H */
diff --git a/reactos/drivers/filesystems/ext2_new/inc/linux/ext4_ext.h b/reactos/drivers/filesystems/ext2_new/inc/linux/ext4_ext.h
new file mode 100644 (file)
index 0000000..a4f0638
--- /dev/null
@@ -0,0 +1,257 @@
+#ifndef _LINUX_EXT4_EXT
+#define _LINUX_EXT4_EXT
+
+/*
+ * This is the extent tail on-disk structure.
+ * All other extent structures are 12 bytes long.  It turns out that
+ * block_size % 12 >= 4 for at least all powers of 2 greater than 512, which
+ * covers all valid ext4 block sizes.  Therefore, this tail structure can be
+ * crammed into the end of the block without having to rebalance the tree.
+ */
+struct ext4_extent_tail {
+       uint32_t et_checksum; /* crc32c(uuid+inum+extent_block) */
+};
+
+/*
+ * This is the extent on-disk structure.
+ * It's used at the bottom of the tree.
+ */
+typedef struct ext4_extent {
+    uint32_t ee_block; /* first logical block extent covers */
+    uint16_t ee_len; /* number of blocks covered by extent */
+    uint16_t ee_start_hi; /* high 16 bits of physical block */
+    uint32_t ee_start_lo; /* low 32 bits of physical block */
+} __attribute__ ((__packed__)) EXT4_EXTENT;
+
+/*
+ * This is index on-disk structure.
+ * It's used at all the levels except the bottom.
+ */
+typedef struct ext4_extent_idx {
+    uint32_t  ei_block;       /* index covers logical blocks from 'block' */
+    uint32_t  ei_leaf_lo;     /* pointer to the physical block of the next *
+                                 * level. leaf or next index could be there */
+    uint16_t  ei_leaf_hi;     /* high 16 bits of physical block */
+    uint16_t   ei_unused;
+}__attribute__ ((__packed__)) EXT4_EXTENT_IDX;
+
+/*
+ * Each block (leaves and indexes), even inode-stored has header.
+ */
+typedef struct ext4_extent_header {
+    uint16_t  eh_magic;       /* probably will support different formats */
+    uint16_t  eh_entries;     /* number of valid entries */
+    uint16_t  eh_max;         /* capacity of store in entries */
+    uint16_t  eh_depth;       /* has tree real underlying blocks? */
+    uint32_t  eh_generation;  /* generation of the tree */
+}__attribute__ ((__packed__)) EXT4_EXTENT_HEADER;
+
+
+#define EXT4_EXT_MAGIC          0xf30a
+#define get_ext4_header(i)      ((struct ext4_extent_header *) (i)->i_block)
+
+#define EXT4_EXTENT_TAIL_OFFSET(hdr)                                           \
+       (sizeof(struct ext4_extent_header) +                                   \
+        (sizeof(struct ext4_extent) * (hdr)->eh_max))
+
+static inline struct ext4_extent_tail *
+find_ext4_extent_tail(struct ext4_extent_header *eh)
+{
+       return (struct ext4_extent_tail *)(((char *)eh) +
+                                          EXT4_EXTENT_TAIL_OFFSET(eh));
+}
+
+/*
+ * Array of ext4_ext_path contains path to some extent.
+ * Creation/lookup routines use it for traversal/splitting/etc.
+ * Truncate uses it to simulate recursive walking.
+ */
+struct ext4_ext_path
+{
+       ext4_fsblk_t p_block;
+       int p_depth;
+       int p_maxdepth;
+       struct ext4_extent *p_ext;
+       struct ext4_extent_idx *p_idx;
+       struct ext4_extent_header *p_hdr;
+       struct buffer_head *p_bh;
+};
+
+/*
+ * structure for external API
+ */
+
+/*
+ * EXT_INIT_MAX_LEN is the maximum number of blocks we can have in an
+ * initialized extent. This is 2^15 and not (2^16 - 1), since we use the
+ * MSB of ee_len field in the extent datastructure to signify if this
+ * particular extent is an initialized extent or an uninitialized (i.e.
+ * preallocated).
+ * EXT_UNINIT_MAX_LEN is the maximum number of blocks we can have in an
+ * uninitialized extent.
+ * If ee_len is <= 0x8000, it is an initialized extent. Otherwise, it is an
+ * uninitialized one. In other words, if MSB of ee_len is set, it is an
+ * uninitialized extent with only one special scenario when ee_len = 0x8000.
+ * In this case we can not have an uninitialized extent of zero length and
+ * thus we make it as a special case of initialized extent with 0x8000 length.
+ * This way we get better extent-to-group alignment for initialized extents.
+ * Hence, the maximum number of blocks we can have in an *initialized*
+ * extent is 2^15 (32768) and in an *uninitialized* extent is 2^15-1 (32767).
+ */
+#define EXT_INIT_MAX_LEN (1UL << 15)
+#define EXT_UNWRITTEN_MAX_LEN  (EXT_INIT_MAX_LEN - 1)
+
+#define EXT_EXTENT_SIZE sizeof(struct ext4_extent)
+#define EXT_INDEX_SIZE sizeof(struct ext4_extent_idx)
+
+#define EXT_FIRST_EXTENT(__hdr__)                                              \
+       ((struct ext4_extent *)(((char *)(__hdr__)) +                          \
+                               sizeof(struct ext4_extent_header)))
+#define EXT_FIRST_INDEX(__hdr__)                                               \
+       ((struct ext4_extent_idx *)(((char *)(__hdr__)) +                      \
+                                   sizeof(struct ext4_extent_header)))
+#define EXT_HAS_FREE_INDEX(__path__)                                           \
+       ((__path__)->p_hdr->eh_entries < (__path__)->p_hdr->eh_max)
+#define EXT_LAST_EXTENT(__hdr__)                                               \
+       (EXT_FIRST_EXTENT((__hdr__)) + (__hdr__)->eh_entries - 1)
+#define EXT_LAST_INDEX(__hdr__)                                                \
+       (EXT_FIRST_INDEX((__hdr__)) + (__hdr__)->eh_entries - 1)
+#define EXT_MAX_EXTENT(__hdr__)                                                \
+       (EXT_FIRST_EXTENT((__hdr__)) + (__hdr__)->eh_max - 1)
+#define EXT_MAX_INDEX(__hdr__)                                                 \
+       (EXT_FIRST_INDEX((__hdr__)) + (__hdr__)->eh_max - 1)
+
+static inline struct ext4_extent_header *ext_inode_hdr(struct inode *inode)
+{
+       return get_ext4_header(inode);
+}
+
+static inline struct ext4_extent_header *ext_block_hdr(struct buffer_head *bh)
+{
+       return (struct ext4_extent_header *)bh->b_data;
+}
+
+static inline unsigned short ext_depth(struct inode *inode)
+{
+       return ext_inode_hdr(inode)->eh_depth;
+}
+
+static inline void ext4_ext_mark_uninitialized(struct ext4_extent *ext)
+{
+       /* We can not have an uninitialized extent of zero length! */
+       ext->ee_len |= EXT_INIT_MAX_LEN;
+}
+
+static inline int ext4_ext_is_uninitialized(struct ext4_extent *ext)
+{
+       /* Extent with ee_len of 0x8000 is treated as an initialized extent */
+       return (ext->ee_len > EXT_INIT_MAX_LEN);
+}
+
+static inline uint16_t ext4_ext_get_actual_len(struct ext4_extent *ext)
+{
+       return (ext->ee_len <= EXT_INIT_MAX_LEN
+                   ? ext->ee_len
+                   : (ext->ee_len - EXT_INIT_MAX_LEN));
+}
+
+static inline void ext4_ext_mark_initialized(struct ext4_extent *ext)
+{
+       ext->ee_len = ext4_ext_get_actual_len(ext);
+}
+
+static inline void ext4_ext_mark_unwritten(struct ext4_extent *ext)
+{
+       /* We can not have an unwritten extent of zero length! */
+       ext->ee_len |= EXT_INIT_MAX_LEN;
+}
+
+static inline int ext4_ext_is_unwritten(struct ext4_extent *ext)
+{
+       /* Extent with ee_len of 0x8000 is treated as an initialized extent */
+       return (ext->ee_len > EXT_INIT_MAX_LEN);
+}
+
+/*
+ * ext4_ext_pblock:
+ * combine low and high parts of physical block number into ext4_fsblk_t
+ */
+static inline ext4_fsblk_t ext4_ext_pblock(struct ext4_extent *ex)
+{
+       ext4_fsblk_t block;
+
+       block = ex->ee_start_lo;
+       block |= ((ext4_fsblk_t)ex->ee_start_hi << 31) << 1;
+       return block;
+}
+
+/*
+ * ext4_idx_pblock:
+ * combine low and high parts of a leaf physical block number into ext4_fsblk_t
+ */
+static inline ext4_fsblk_t ext4_idx_pblock(struct ext4_extent_idx *ix)
+{
+       ext4_fsblk_t block;
+
+       block = ix->ei_leaf_lo;
+       block |= ((ext4_fsblk_t)ix->ei_leaf_hi << 31) << 1;
+       return block;
+}
+
+/*
+ * ext4_ext_store_pblock:
+ * stores a large physical block number into an extent struct,
+ * breaking it into parts
+ */
+static inline void ext4_ext_store_pblock(struct ext4_extent *ex,
+                                        ext4_fsblk_t pb)
+{
+       ex->ee_start_lo = (uint32_t)(pb & 0xffffffff);
+       ex->ee_start_hi = (uint16_t)((pb >> 31) >> 1) & 0xffff;
+}
+
+/*
+ * ext4_idx_store_pblock:
+ * stores a large physical block number into an index struct,
+ * breaking it into parts
+ */
+static inline void ext4_idx_store_pblock(struct ext4_extent_idx *ix,
+                                        ext4_fsblk_t pb)
+{
+       ix->ei_leaf_lo = (uint32_t)(pb & 0xffffffff);
+       ix->ei_leaf_hi = (uint16_t)((pb >> 31) >> 1) & 0xffff;
+}
+
+#define ext4_ext_dirty(icb, handle, inode, path)                                           \
+       __ext4_ext_dirty("", __LINE__, (icb), (handle), (inode), (path))
+
+#define INODE_HAS_EXTENT(i) ((i)->i_flags & EXT2_EXTENTS_FL)
+
+static inline uint64_t ext_to_block(EXT4_EXTENT *extent)
+{
+    uint64_t block;
+
+    block = (uint64_t)extent->ee_start_lo;
+    block |= ((uint64_t) extent->ee_start_hi << 31) << 1;
+
+    return block;
+}
+
+static inline uint64_t idx_to_block(EXT4_EXTENT_IDX *idx)
+{
+    uint64_t block;
+
+    block = (uint64_t)idx->ei_leaf_lo;
+    block |= ((uint64_t) idx->ei_leaf_hi << 31) << 1;
+
+    return block;
+}
+
+
+int ext4_ext_get_blocks(void *icb, handle_t *handle, struct inode *inode, ext4_fsblk_t iblock,
+                       unsigned long max_blocks, struct buffer_head *bh_result,
+                       int create, int flags);
+int ext4_ext_tree_init(void *icb, handle_t *handle, struct inode *inode);
+int ext4_ext_remove_space(void *icb, struct inode *inode, unsigned long start);
+
+#endif /* _LINUX_EXT4_EXT */
diff --git a/reactos/drivers/filesystems/ext2_new/inc/linux/ext4_jbd2.h b/reactos/drivers/filesystems/ext2_new/inc/linux/ext4_jbd2.h
new file mode 100644 (file)
index 0000000..d6c6fea
--- /dev/null
@@ -0,0 +1,65 @@
+#ifndef _EXT4_JBD2_H
+#define _EXT4_JBD2_H
+
+/*
+ * Wrapper functions with which ext4 calls into JBD.
+ */
+void ext4_journal_abort_handle(const char *caller, unsigned int line,
+                              const char *err_fn, struct buffer_head *bh,
+                              handle_t *handle, int err);
+
+int __ext4_handle_dirty_super(const char *where, unsigned int line,
+                             handle_t *handle, struct super_block *sb);
+
+int __ext4_journal_get_write_access(const char *where, unsigned int line,
+                                   void *icb, handle_t *handle, struct buffer_head *bh);
+
+int __ext4_forget(const char *where, unsigned int line, void *icb, handle_t *handle,
+                 int is_metadata, struct inode *inode,
+                 struct buffer_head *bh, ext4_fsblk_t blocknr);
+
+int __ext4_journal_get_create_access(const char *where, unsigned int line,
+                               void *icb, handle_t *handle, struct buffer_head *bh);
+
+int __ext4_handle_dirty_metadata(const char *where, unsigned int line,
+                                void *icb, handle_t *handle, struct inode *inode,
+                                struct buffer_head *bh);
+
+#define ext4_journal_get_write_access(handle, icb, bh) \
+       __ext4_journal_get_write_access("", __LINE__, (icb), (handle), (bh))
+#define ext4_forget(handle, icb, is_metadata, inode, bh, block_nr) \
+       __ext4_forget("", __LINE__, (icb), (handle), (is_metadata), (inode), \
+                     (bh), (block_nr))
+#define ext4_journal_get_create_access(handle, icb, bh) \
+       __ext4_journal_get_create_access("", __LINE__, (icb), (handle), (bh))
+#define ext4_handle_dirty_metadata(handle, icb, inode, bh) \
+       __ext4_handle_dirty_metadata("", __LINE__, (icb), (handle), (inode), \
+                                    (bh))
+
+handle_t *__ext4_journal_start_sb(void *icb, struct super_block *sb, unsigned int line,
+                                 int type, int blocks, int rsv_blocks);
+int __ext4_journal_stop(const char *where, unsigned int line, void *icb, handle_t *handle);
+
+#define ext4_journal_start_sb(icb, sb, type, nblocks)                  \
+       __ext4_journal_start_sb((icb), (sb), __LINE__, (type), (nblocks), 0)
+
+#define ext4_journal_start(icb, inode, type, nblocks)                  \
+       __ext4_journal_start((icb), (inode), __LINE__, (type), (nblocks), 0)
+
+static inline handle_t *__ext4_journal_start(void *icb, struct inode *inode,
+                                            unsigned int line, int type,
+                                            int blocks, int rsv_blocks)
+{
+       return __ext4_journal_start_sb(icb, inode->i_sb, line, type, blocks,
+                                      rsv_blocks);
+}
+
+#define ext4_journal_stop(icb, handle) \
+       __ext4_journal_stop("", __LINE__, (icb), (handle))
+
+static inline int ext4_journal_extend(void *icb, handle_t *handle, int nblocks)
+{
+       return 0;
+}
+
+#endif
diff --git a/reactos/drivers/filesystems/ext2_new/inc/linux/fs.h b/reactos/drivers/filesystems/ext2_new/inc/linux/fs.h
new file mode 100644 (file)
index 0000000..69aecbd
--- /dev/null
@@ -0,0 +1,156 @@
+#ifndef _LINUX_FS_INCLUDE_
+#define _LINUX_FS_INCLUDE_
+
+#include <linux/types.h>
+#include <linux/atomic.h>
+
+//
+// kdev
+//
+
+#define NODEV           0
+
+typedef struct block_device * kdev_t;
+
+#define MINORBITS   8
+#define MINORMASK   ((1U << MINORBITS) - 1)
+
+#define MAJOR(dev)   ((unsigned int)((int)(dev) >> MINORBITS))
+#define MINOR(dev)   ((unsigned int)((int)(dev) & MINORMASK))
+
+static inline unsigned int kdev_t_to_nr(kdev_t dev) {
+    /*return (unsigned int)(MAJOR(dev)<<8) | MINOR(dev);*/
+    return 0;
+}
+
+#define NODEV          0
+#define MKDEV(ma,mi)   (((ma) << MINORBITS) | (mi))
+
+static inline kdev_t to_kdev_t(int dev)
+{
+#if 0
+    int major, minor;
+#if 0
+    major = (dev >> 16);
+    if (!major) {
+        major = (dev >> 8);
+        minor = (dev & 0xff);
+    } else
+        minor = (dev & 0xffff);
+#else
+    major = (dev >> 8);
+    minor = (dev & 0xff);
+#endif
+    return (kdev_t) MKDEV(major, minor);
+#endif
+    return 0;
+}
+
+
+//
+// file system specific structures
+//
+
+/*
+ * Kernel pointers have redundant information, so we can use a
+ * scheme where we can return either an error code or a dentry
+ * pointer with the same return value.
+ *
+ * This should be a per-architecture thing, to allow different
+ * error and pointer decisions.
+ */
+
+struct super_block {
+    unsigned long       s_magic;
+    unsigned long       s_flags;
+    unsigned long              s_blocksize;        /* blocksize */
+    unsigned long long  s_maxbytes;
+    unsigned char              s_blocksize_bits;   /* bits of blocksize */
+    unsigned char              s_dirt;             /* any thing */
+    char                s_id[30];           /* id string */
+    kdev_t              s_bdev;             /* block_device */
+    void *              s_priv;             /* EXT2_VCB */
+    struct dentry      *s_root;
+    void               *s_fs_info;
+};
+
+struct inode {
+    __u32               i_ino;              /* inode number */
+    loff_t                         i_size;             /* size */
+    __u32               i_atime;               /* Access time */
+    __u32               i_ctime;               /* Creation time */
+    __u32               i_mtime;               /* Modification time */
+    __u32               i_dtime;               /* Deletion Time */
+    __u64               i_blocks;
+    __u32               i_block[15];
+    umode_t                        i_mode;             /* mode */
+    uid_t               i_uid;
+    gid_t               i_gid;
+    atomic_t            i_count;            /* ref count */
+    __u16               i_nlink;
+    __u32               i_generation;
+    __u32               i_version;
+    __u32               i_flags;
+
+    struct super_block *i_sb;               /* super_block */
+    void               *i_priv;             /* EXT2_MCB */
+};
+
+//
+//  Inode state bits
+//
+
+#define I_DIRTY_SYNC        1 /* Not dirty enough for O_DATASYNC */
+#define I_DIRTY_DATASYNC    2 /* Data-related inode changes pending */
+#define I_DIRTY_PAGES       4 /* Data-related inode changes pending */
+#define I_LOCK              8
+#define I_FREEING          16
+#define I_CLEAR            32
+
+#define I_DIRTY (I_DIRTY_SYNC | I_DIRTY_DATASYNC | I_DIRTY_PAGES)
+
+
+struct dentry {
+    atomic_t                d_count;
+    struct {
+        int             len;
+        char           *name;
+    } d_name;
+    struct inode           *d_inode;
+    struct dentry          *d_parent;
+    void                   *d_fsdata;
+    struct super_block     *d_sb;
+};
+
+struct file {
+
+    unsigned int    f_flags;
+    umode_t         f_mode;
+    __u32           f_version;
+    __int64         f_size;
+    loff_t          f_pos;
+    struct dentry  *f_dentry;
+    void           *private_data;
+};
+
+/*
+ * File types
+ *
+ * NOTE! These match bits 12..15 of stat.st_mode
+ * (ie "(i_mode >> 12) & 15").
+ */
+#define DT_UNKNOWN     0
+#define DT_FIFO                1
+#define DT_CHR         2
+#define DT_DIR         4
+#define DT_BLK         6
+#define DT_REG         8
+#define DT_LNK         10
+#define DT_SOCK                12
+#define DT_WHT         14
+
+void iget(struct inode *inode);
+void iput(struct inode *inode);
+ULONGLONG bmap(struct inode *i, ULONGLONG b);
+
+#endif /*_LINUX_FS_INCLUDE_*/
\ No newline at end of file
diff --git a/reactos/drivers/filesystems/ext2_new/inc/linux/group.h b/reactos/drivers/filesystems/ext2_new/inc/linux/group.h
new file mode 100644 (file)
index 0000000..32614cf
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ *  linux/fs/ext4/group.h
+ *
+ * Copyright (C) 2007 Cluster File Systems, Inc
+ *
+ * Author: Andreas Dilger <adilger@clusterfs.com>
+ */
+
+#ifndef _LINUX_EXT4_GROUP_H
+#define _LINUX_EXT4_GROUP_H
+
+extern __le16 ext4_group_desc_csum(struct ext4_sb_info *sbi, __u32 group,
+                                       struct ext4_group_desc *gdp);
+extern int ext4_group_desc_csum_verify(struct ext4_sb_info *sbi, __u32 group,
+                                           struct ext4_group_desc *gdp);
+struct buffer_head *ext4_read_block_bitmap(struct super_block *sb,
+                    ext4_group_t block_group);
+extern unsigned ext4_init_block_bitmap(struct super_block *sb,
+                                           struct buffer_head *bh,
+                                           ext4_group_t group,
+                                           struct ext4_group_desc *desc);
+#define ext4_free_blocks_after_init(sb, group, desc)                   \
+               ext4_init_block_bitmap(sb, NULL, group, desc)
+extern unsigned ext4_init_inode_bitmap(struct super_block *sb,
+                                           struct buffer_head *bh,
+                                           ext4_group_t group,
+                                           struct ext4_group_desc *desc);
+extern void mark_bitmap_end(int start_bit, int end_bit, char *bitmap);
+#endif /* _LINUX_EXT4_GROUP_H */
diff --git a/reactos/drivers/filesystems/ext2_new/inc/linux/jbd.h b/reactos/drivers/filesystems/ext2_new/inc/linux/jbd.h
new file mode 100644 (file)
index 0000000..60badad
--- /dev/null
@@ -0,0 +1,1111 @@
+/*
+ * linux/include/linux/jbd.h
+ *
+ * Written by Stephen C. Tweedie <sct@redhat.com>
+ *
+ * Copyright 1998-2000 Red Hat, Inc --- All Rights Reserved
+ *
+ * This file is part of the Linux kernel and is made available under
+ * the terms of the GNU General Public License, version 2, or at your
+ * option, any later version, incorporated herein by reference.
+ *
+ * Definitions for transaction data structures for the buffer cache
+ * filesystem journaling support.
+ */
+
+#ifndef _LINUX_JBD_H
+#define _LINUX_JBD_H
+
+/* Allow this file to be included directly into e2fsprogs */
+#ifndef __KERNEL__
+#include "jfs_compat.h"
+#define JFS_DEBUG
+#define jfs_debug jbd_debug
+#else
+
+#include <linux/module.h>
+#include <linux/buffer_head.h>
+#include <linux/journal-head.h>
+#include <linux/stddef.h>
+#include <linux/bit_spinlock.h>
+#include <linux/mutex.h>
+#include <linux/timer.h>
+#include <linux/lockdep.h>
+
+#include <asm/semaphore.h>
+
+#define journal_oom_retry 1
+
+/*
+ * Define JBD_PARANIOD_IOFAIL to cause a kernel BUG() if ext3 finds
+ * certain classes of error which can occur due to failed IOs.  Under
+ * normal use we want ext3 to continue after such errors, because
+ * hardware _can_ fail, but for debugging purposes when running tests on
+ * known-good hardware we may want to trap these errors.
+ */
+#undef JBD_PARANOID_IOFAIL
+
+/*
+ * The default maximum commit age, in seconds.
+ */
+#define JBD_DEFAULT_MAX_COMMIT_AGE 5
+
+#ifdef CONFIG_JBD_DEBUG
+/*
+ * Define JBD_EXPENSIVE_CHECKING to enable more expensive internal
+ * consistency checks.  By default we don't do this unless
+ * CONFIG_JBD_DEBUG is on.
+ */
+#define JBD_EXPENSIVE_CHECKING
+extern u8 journal_enable_debug;
+
+#define jbd_debug(n, f, a...)                                          \
+       do {                                                            \
+               if ((n) <= journal_enable_debug) {                      \
+                       printk (KERN_DEBUG "(%s, %d): %s: ",            \
+                               __FILE__, __LINE__, __FUNCTION__);      \
+                       printk (f, ## a);                               \
+               }                                                       \
+       } while (0)
+#else
+#define jbd_debug
+#endif
+
+static inline void *jbd_alloc(size_t size, gfp_t flags)
+{
+    return kmalloc(size, flags);
+    /*__get_free_pages(flags, get_order(size));*/
+}
+
+static inline void jbd_free(void *ptr, size_t size)
+{
+    if (ptr) {
+        kfree(ptr);
+    }
+    /* free_pages((unsigned long)ptr, get_order(size)); */
+};
+
+#define JFS_MIN_JOURNAL_BLOCKS 1024
+
+
+/**
+ * typedef handle_t - The handle_t type represents a single atomic update being performed by some process.
+ *
+ * All filesystem modifications made by the process go
+ * through this handle.  Recursive operations (such as quota operations)
+ * are gathered into a single update.
+ *
+ * The buffer credits field is used to account for journaled buffers
+ * being modified by the running process.  To ensure that there is
+ * enough log space for all outstanding operations, we need to limit the
+ * number of outstanding buffers possible at any time.  When the
+ * operation completes, any buffer credits not used are credited back to
+ * the transaction, so that at all times we know how many buffers the
+ * outstanding updates on a transaction might possibly touch.
+ *
+ * This is an opaque datatype.
+ **/
+typedef struct handle_s                handle_t;       /* Atomic operation type */
+
+
+/**
+ * typedef journal_t - The journal_t maintains all of the journaling state information for a single filesystem.
+ *
+ * journal_t is linked to from the fs superblock structure.
+ *
+ * We use the journal_t to keep track of all outstanding transaction
+ * activity on the filesystem, and to manage the state of the log
+ * writing process.
+ *
+ * This is an opaque datatype.
+ **/
+typedef struct journal_s       journal_t;      /* Journal control structure */
+#endif
+
+/*
+ * Internal structures used by the logging mechanism:
+ */
+
+#define JFS_MAGIC_NUMBER 0xc03b3998U /* The first 4 bytes of /dev/random! */
+
+/*
+ * On-disk structures
+ */
+
+/*
+ * Descriptor block types:
+ */
+
+#define JFS_DESCRIPTOR_BLOCK   1
+#define JFS_COMMIT_BLOCK       2
+#define JFS_SUPERBLOCK_V1      3
+#define JFS_SUPERBLOCK_V2      4
+#define JFS_REVOKE_BLOCK       5
+
+/*
+ * Standard header for all descriptor blocks:
+ */
+typedef struct journal_header_s
+{
+    __be32             h_magic;
+    __be32             h_blocktype;
+    __be32             h_sequence;
+} journal_header_t;
+
+
+/*
+ * The block tag: used to describe a single buffer in the journal
+ */
+typedef struct journal_block_tag_s
+{
+    __be32             t_blocknr;      /* The on-disk block number */
+    __be32             t_flags;        /* See below */
+} journal_block_tag_t;
+
+/*
+ * The revoke descriptor: used on disk to describe a series of blocks to
+ * be revoked from the log
+ */
+typedef struct journal_revoke_header_s
+{
+    journal_header_t r_header;
+    __be32              r_count;       /* Count of bytes used in the block */
+} journal_revoke_header_t;
+
+
+/* Definitions for the journal tag flags word: */
+#define JFS_FLAG_ESCAPE                1       /* on-disk block is escaped */
+#define JFS_FLAG_SAME_UUID     2       /* block has same uuid as previous */
+#define JFS_FLAG_DELETED       4       /* block deleted by this transaction */
+#define JFS_FLAG_LAST_TAG      8       /* last tag in this descriptor block */
+
+
+/*
+ * The journal superblock.  All fields are in big-endian byte order.
+ */
+typedef struct journal_superblock_s
+{
+    /* 0x0000 */
+    journal_header_t s_header;
+
+    /* 0x000C */
+    /* Static information describing the journal */
+    __be32     s_blocksize;            /* journal device blocksize */
+    __be32     s_maxlen;               /* total blocks in journal file */
+    __be32     s_first;                /* first block of log information */
+
+    /* 0x0018 */
+    /* Dynamic information describing the current state of the log */
+    __be32     s_sequence;             /* first commit ID expected in log */
+    __be32     s_start;                /* blocknr of start of log */
+
+    /* 0x0020 */
+    /* Error value, as set by journal_abort(). */
+    __be32     s_errno;
+
+    /* 0x0024 */
+    /* Remaining fields are only valid in a version-2 superblock */
+    __be32     s_feature_compat;       /* compatible feature set */
+    __be32     s_feature_incompat;     /* incompatible feature set */
+    __be32     s_feature_ro_compat;    /* readonly-compatible feature set */
+    /* 0x0030 */
+    __u8       s_uuid[16];             /* 128-bit uuid for journal */
+
+    /* 0x0040 */
+    __be32     s_nr_users;             /* Nr of filesystems sharing log */
+
+    __be32     s_dynsuper;             /* Blocknr of dynamic superblock copy*/
+
+    /* 0x0048 */
+    __be32     s_max_transaction;      /* Limit of journal blocks per trans.*/
+    __be32     s_max_trans_data;       /* Limit of data blocks per trans. */
+
+    /* 0x0050 */
+    __u32      s_padding[44];
+
+    /* 0x0100 */
+    __u8       s_users[16*48];         /* ids of all fs'es sharing the log */
+    /* 0x0400 */
+} journal_superblock_t;
+
+#define JFS_HAS_COMPAT_FEATURE(j,mask)                                 \
+       ((j)->j_format_version >= 2 &&                                  \
+        ((j)->j_superblock->s_feature_compat & cpu_to_be32((mask))))
+#define JFS_HAS_RO_COMPAT_FEATURE(j,mask)                              \
+       ((j)->j_format_version >= 2 &&                                  \
+        ((j)->j_superblock->s_feature_ro_compat & cpu_to_be32((mask))))
+#define JFS_HAS_INCOMPAT_FEATURE(j,mask)                               \
+       ((j)->j_format_version >= 2 &&                                  \
+        ((j)->j_superblock->s_feature_incompat & cpu_to_be32((mask))))
+
+#define JFS_FEATURE_INCOMPAT_REVOKE    0x00000001
+
+/* Features known to this kernel version: */
+#define JFS_KNOWN_COMPAT_FEATURES      0
+#define JFS_KNOWN_ROCOMPAT_FEATURES    0
+#define JFS_KNOWN_INCOMPAT_FEATURES    JFS_FEATURE_INCOMPAT_REVOKE
+
+#ifdef __KERNEL__
+
+#include <linux/fs.h>
+#include <linux/sched.h>
+
+#define J_ASSERT  ASSERT
+
+#if defined(CONFIG_BUFFER_DEBUG)
+void buffer_assertion_failure(struct buffer_head *bh);
+#define J_ASSERT_BH(bh, expr)                                          \
+       do {                                                            \
+               if (!(expr))                                            \
+                       buffer_assertion_failure(bh);                   \
+               J_ASSERT(expr);                                         \
+       } while (0)
+#define J_ASSERT_JH(jh, expr)  J_ASSERT_BH(jh2bh(jh), expr)
+#else
+#define J_ASSERT_BH(bh, expr)  J_ASSERT(expr)
+#define J_ASSERT_JH(jh, expr)  J_ASSERT(expr)
+#endif
+
+#if defined(JBD_PARANOID_IOFAIL)
+#define J_EXPECT(expr, why...)         J_ASSERT(expr)
+#define J_EXPECT_BH(bh, expr, why...)  J_ASSERT_BH(bh, expr)
+#define J_EXPECT_JH(jh, expr, why...)  J_ASSERT_JH(jh, expr)
+#else
+#if 0
+#define __journal_expect(expr, why...)                                      \
+       ({                                                                   \
+               int val = (expr);                                            \
+               if (!val) {                                                  \
+                       printk(KERN_ERR                                      \
+                               "EXT3-fs unexpected failure: %s;\n",# expr); \
+                       printk(KERN_ERR why "\n");                           \
+               }                                                            \
+               val;                                                         \
+       })
+#define J_EXPECT(expr, why...)         __journal_expect(expr, ## why)
+#define J_EXPECT_BH(bh, expr, why...)  __journal_expect(expr, ## why)
+#define J_EXPECT_JH(jh, expr, why...)  __journal_expect(expr, ## why)
+#endif
+#define __journal_expect
+
+#define J_EXPECT
+#define J_EXPECT_BH
+#define J_EXPECT_JH
+
+#endif
+
+enum jbd_state_bits {
+    BH_JBD                     /* Has an attached ext3 journal_head */
+    = BH_PrivateStart,
+    BH_JWrite,         /* Being written to log (@@@ DEBUGGING) */
+    BH_Freed,          /* Has been freed (truncated) */
+    BH_Revoked,                /* Has been revoked from the log */
+    BH_RevokeValid,            /* Revoked flag is valid */
+    BH_JBDDirty,               /* Is dirty but journaled */
+    BH_State,          /* Pins most journal_head state */
+    BH_JournalHead,            /* Pins bh->b_private and jh->b_bh */
+    BH_Unshadow,               /* Dummy bit, for BJ_Shadow wakeup filtering */
+};
+
+BUFFER_FNS(JBD, jbd)
+BUFFER_FNS(JWrite, jwrite)
+BUFFER_FNS(JBDDirty, jbddirty)
+TAS_BUFFER_FNS(JBDDirty, jbddirty)
+BUFFER_FNS(Revoked, revoked)
+TAS_BUFFER_FNS(Revoked, revoked)
+BUFFER_FNS(RevokeValid, revokevalid)
+TAS_BUFFER_FNS(RevokeValid, revokevalid)
+BUFFER_FNS(Freed, freed)
+
+static inline struct buffer_head *jh2bh(struct journal_head *jh)
+{
+    return jh->b_bh;
+}
+
+static inline struct journal_head *bh2jh(struct buffer_head *bh)
+{
+    return bh->b_private;
+}
+
+static inline void jbd_lock_bh_state(struct buffer_head *bh)
+{
+    bit_spin_lock(BH_State, &bh->b_state);
+}
+
+static inline int jbd_trylock_bh_state(struct buffer_head *bh)
+{
+    return bit_spin_trylock(BH_State, &bh->b_state);
+}
+
+static inline int jbd_is_locked_bh_state(struct buffer_head *bh)
+{
+    return bit_spin_is_locked(BH_State, &bh->b_state);
+}
+
+static inline void jbd_unlock_bh_state(struct buffer_head *bh)
+{
+    bit_spin_unlock(BH_State, &bh->b_state);
+}
+
+static inline void jbd_lock_bh_journal_head(struct buffer_head *bh)
+{
+    bit_spin_lock(BH_JournalHead, &bh->b_state);
+}
+
+static inline void jbd_unlock_bh_journal_head(struct buffer_head *bh)
+{
+    bit_spin_unlock(BH_JournalHead, &bh->b_state);
+}
+
+struct jbd_revoke_table_s;
+
+/**
+ * struct handle_s - The handle_s type is the concrete type associated with
+ *     handle_t.
+ * @h_transaction: Which compound transaction is this update a part of?
+ * @h_buffer_credits: Number of remaining buffers we are allowed to dirty.
+ * @h_ref: Reference count on this handle
+ * @h_err: Field for caller's use to track errors through large fs operations
+ * @h_sync: flag for sync-on-close
+ * @h_jdata: flag to force data journaling
+ * @h_aborted: flag indicating fatal error on handle
+ * @h_lockdep_map: lockdep info for debugging lock problems
+ **/
+
+/* Docbook can't yet cope with the bit fields, but will leave the documentation
+ * in so it can be fixed later.
+ */
+
+struct handle_s
+{
+    /* Which compound transaction is this update a part of? */
+    transaction_t              *h_transaction;
+
+    /* Number of remaining buffers we are allowed to dirty: */
+    int                        h_buffer_credits;
+
+    /* Reference count on this handle */
+    int                        h_ref;
+
+    /* Field for caller's use to track errors through large fs */
+    /* operations */
+    int                        h_err;
+
+    /* Flags [no locking] */
+unsigned int   h_sync:
+    1; /* sync-on-close */
+unsigned int   h_jdata:
+    1; /* force data journaling */
+unsigned int   h_aborted:
+    1; /* fatal error on handle */
+
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+    struct lockdep_map h_lockdep_map;
+#endif
+};
+
+
+/* The transaction_t type is the guts of the journaling mechanism.  It
+ * tracks a compound transaction through its various states:
+ *
+ * RUNNING:    accepting new updates
+ * LOCKED:     Updates still running but we don't accept new ones
+ * RUNDOWN:    Updates are tidying up but have finished requesting
+ *             new buffers to modify (state not used for now)
+ * FLUSH:       All updates complete, but we are still writing to disk
+ * COMMIT:      All data on disk, writing commit record
+ * FINISHED:   We still have to keep the transaction for checkpointing.
+ *
+ * The transaction keeps track of all of the buffers modified by a
+ * running transaction, and all of the buffers committed but not yet
+ * flushed to home for finished transactions.
+ */
+
+/*
+ * Lock ranking:
+ *
+ *    j_list_lock
+ *      ->jbd_lock_bh_journal_head()   (This is "innermost")
+ *
+ *    j_state_lock
+ *    ->jbd_lock_bh_state()
+ *
+ *    jbd_lock_bh_state()
+ *    ->j_list_lock
+ *
+ *    j_state_lock
+ *    ->t_handle_lock
+ *
+ *    j_state_lock
+ *    ->j_list_lock                    (journal_unmap_buffer)
+ *
+ */
+
+struct transaction_s
+{
+    /* Pointer to the journal for this transaction. [no locking] */
+    journal_t          *t_journal;
+
+    /* Sequence number for this transaction [no locking] */
+    tid_t                      t_tid;
+
+    /*
+     * Transaction's current state
+     * [no locking - only kjournald alters this]
+     * [j_list_lock] guards transition of a transaction into T_FINISHED
+     * state and subsequent call of __journal_drop_transaction()
+     * FIXME: needs barriers
+     * KLUDGE: [use j_state_lock]
+     */
+    enum {
+        T_RUNNING,
+        T_LOCKED,
+        T_RUNDOWN,
+        T_FLUSH,
+        T_COMMIT,
+        T_FINISHED
+    }                  t_state;
+
+    /*
+     * Where in the log does this transaction's commit start? [no locking]
+     */
+    unsigned long              t_log_start;
+
+    /* Number of buffers on the t_buffers list [j_list_lock] */
+    int                        t_nr_buffers;
+
+    /*
+     * Doubly-linked circular list of all buffers reserved but not yet
+     * modified by this transaction [j_list_lock]
+     */
+    struct journal_head        *t_reserved_list;
+
+    /*
+     * Doubly-linked circular list of all buffers under writeout during
+     * commit [j_list_lock]
+     */
+    struct journal_head        *t_locked_list;
+
+    /*
+     * Doubly-linked circular list of all metadata buffers owned by this
+     * transaction [j_list_lock]
+     */
+    struct journal_head        *t_buffers;
+
+    /*
+     * Doubly-linked circular list of all data buffers still to be
+     * flushed before this transaction can be committed [j_list_lock]
+     */
+    struct journal_head        *t_sync_datalist;
+
+    /*
+     * Doubly-linked circular list of all forget buffers (superseded
+     * buffers which we can un-checkpoint once this transaction commits)
+     * [j_list_lock]
+     */
+    struct journal_head        *t_forget;
+
+    /*
+     * Doubly-linked circular list of all buffers still to be flushed before
+     * this transaction can be checkpointed. [j_list_lock]
+     */
+    struct journal_head        *t_checkpoint_list;
+
+    /*
+     * Doubly-linked circular list of all buffers submitted for IO while
+     * checkpointing. [j_list_lock]
+     */
+    struct journal_head        *t_checkpoint_io_list;
+
+    /*
+     * Doubly-linked circular list of temporary buffers currently undergoing
+     * IO in the log [j_list_lock]
+     */
+    struct journal_head        *t_iobuf_list;
+
+    /*
+     * Doubly-linked circular list of metadata buffers being shadowed by log
+     * IO.  The IO buffers on the iobuf list and the shadow buffers on this
+     * list match each other one for one at all times. [j_list_lock]
+     */
+    struct journal_head        *t_shadow_list;
+
+    /*
+     * Doubly-linked circular list of control buffers being written to the
+     * log. [j_list_lock]
+     */
+    struct journal_head        *t_log_list;
+
+    /*
+     * Protects info related to handles
+     */
+    spinlock_t         t_handle_lock;
+
+    /*
+     * Number of outstanding updates running on this transaction
+     * [t_handle_lock]
+     */
+    int                        t_updates;
+
+    /*
+     * Number of buffers reserved for use by all handles in this transaction
+     * handle but not yet modified. [t_handle_lock]
+     */
+    int                        t_outstanding_credits;
+
+    /*
+     * Forward and backward links for the circular list of all transactions
+     * awaiting checkpoint. [j_list_lock]
+     */
+    transaction_t              *t_cpnext, *t_cpprev;
+
+    /*
+     * When will the transaction expire (become due for commit), in jiffies?
+     * [no locking]
+     */
+    unsigned long              t_expires;
+
+    /*
+     * How many handles used this transaction? [t_handle_lock]
+     */
+    int t_handle_count;
+
+};
+
+/**
+ * struct journal_s - The journal_s type is the concrete type associated with
+ *     journal_t.
+ * @j_flags:  General journaling state flags
+ * @j_errno:  Is there an outstanding uncleared error on the journal (from a
+ *     prior abort)?
+ * @j_sb_buffer: First part of superblock buffer
+ * @j_superblock: Second part of superblock buffer
+ * @j_format_version: Version of the superblock format
+ * @j_state_lock: Protect the various scalars in the journal
+ * @j_barrier_count:  Number of processes waiting to create a barrier lock
+ * @j_barrier: The barrier lock itself
+ * @j_running_transaction: The current running transaction..
+ * @j_committing_transaction: the transaction we are pushing to disk
+ * @j_checkpoint_transactions: a linked circular list of all transactions
+ *  waiting for checkpointing
+ * @j_wait_transaction_locked: Wait queue for waiting for a locked transaction
+ *  to start committing, or for a barrier lock to be released
+ * @j_wait_logspace: Wait queue for waiting for checkpointing to complete
+ * @j_wait_done_commit: Wait queue for waiting for commit to complete
+ * @j_wait_checkpoint:  Wait queue to trigger checkpointing
+ * @j_wait_commit: Wait queue to trigger commit
+ * @j_wait_updates: Wait queue to wait for updates to complete
+ * @j_checkpoint_mutex: Mutex for locking against concurrent checkpoints
+ * @j_head: Journal head - identifies the first unused block in the journal
+ * @j_tail: Journal tail - identifies the oldest still-used block in the
+ *  journal.
+ * @j_free: Journal free - how many free blocks are there in the journal?
+ * @j_first: The block number of the first usable block
+ * @j_last: The block number one beyond the last usable block
+ * @j_dev: Device where we store the journal
+ * @j_blocksize: blocksize for the location where we store the journal.
+ * @j_blk_offset: starting block offset for into the device where we store the
+ *     journal
+ * @j_fs_dev: Device which holds the client fs.  For internal journal this will
+ *     be equal to j_dev
+ * @j_maxlen: Total maximum capacity of the journal region on disk.
+ * @j_list_lock: Protects the buffer lists and internal buffer state.
+ * @j_inode: Optional inode where we store the journal.  If present, all journal
+ *     block numbers are mapped into this inode via bmap().
+ * @j_tail_sequence:  Sequence number of the oldest transaction in the log
+ * @j_transaction_sequence: Sequence number of the next transaction to grant
+ * @j_commit_sequence: Sequence number of the most recently committed
+ *  transaction
+ * @j_commit_request: Sequence number of the most recent transaction wanting
+ *     commit
+ * @j_uuid: Uuid of client object.
+ * @j_task: Pointer to the current commit thread for this journal
+ * @j_max_transaction_buffers:  Maximum number of metadata buffers to allow in a
+ *     single compound commit transaction
+ * @j_commit_interval: What is the maximum transaction lifetime before we begin
+ *  a commit?
+ * @j_commit_timer:  The timer used to wakeup the commit thread
+ * @j_revoke_lock: Protect the revoke table
+ * @j_revoke: The revoke table - maintains the list of revoked blocks in the
+ *     current transaction.
+ * @j_revoke_table: alternate revoke tables for j_revoke
+ * @j_wbuf: array of buffer_heads for journal_commit_transaction
+ * @j_wbufsize: maximum number of buffer_heads allowed in j_wbuf, the
+ *     number that will fit in j_blocksize
+ * @j_last_sync_writer: most recent pid which did a synchronous write
+ * @j_private: An opaque pointer to fs-private information.
+ */
+
+struct journal_s
+{
+    /* General journaling state flags [j_state_lock] */
+    unsigned long              j_flags;
+
+    /*
+     * Is there an outstanding uncleared error on the journal (from a prior
+     * abort)? [j_state_lock]
+     */
+    int                        j_errno;
+
+    /* The superblock buffer */
+    struct buffer_head *j_sb_buffer;
+    journal_superblock_t       *j_superblock;
+
+    /* Version of the superblock format */
+    int                        j_format_version;
+
+    /*
+     * Protect the various scalars in the journal
+     */
+    spinlock_t         j_state_lock;
+
+    /*
+     * Number of processes waiting to create a barrier lock [j_state_lock]
+     */
+    int                        j_barrier_count;
+
+    /* The barrier lock itself */
+    struct mutex               j_barrier;
+
+    /*
+     * Transactions: The current running transaction...
+     * [j_state_lock] [caller holding open handle]
+     */
+    transaction_t              *j_running_transaction;
+
+    /*
+     * the transaction we are pushing to disk
+     * [j_state_lock] [caller holding open handle]
+     */
+    transaction_t              *j_committing_transaction;
+
+    /*
+     * ... and a linked circular list of all transactions waiting for
+     * checkpointing. [j_list_lock]
+     */
+    transaction_t              *j_checkpoint_transactions;
+
+    /*
+     * Wait queue for waiting for a locked transaction to start committing,
+     * or for a barrier lock to be released
+     */
+    wait_queue_head_t  j_wait_transaction_locked;
+
+    /* Wait queue for waiting for checkpointing to complete */
+    wait_queue_head_t  j_wait_logspace;
+
+    /* Wait queue for waiting for commit to complete */
+    wait_queue_head_t  j_wait_done_commit;
+
+    /* Wait queue to trigger checkpointing */
+    wait_queue_head_t  j_wait_checkpoint;
+
+    /* Wait queue to trigger commit */
+    wait_queue_head_t  j_wait_commit;
+
+    /* Wait queue to wait for updates to complete */
+    wait_queue_head_t  j_wait_updates;
+
+    /* Semaphore for locking against concurrent checkpoints */
+    struct mutex               j_checkpoint_mutex;
+
+    /*
+     * Journal head: identifies the first unused block in the journal.
+     * [j_state_lock]
+     */
+    unsigned long              j_head;
+
+    /*
+     * Journal tail: identifies the oldest still-used block in the journal.
+     * [j_state_lock]
+     */
+    unsigned long              j_tail;
+
+    /*
+     * Journal free: how many free blocks are there in the journal?
+     * [j_state_lock]
+     */
+    unsigned long              j_free;
+
+    /*
+     * Journal start and end: the block numbers of the first usable block
+     * and one beyond the last usable block in the journal. [j_state_lock]
+     */
+    unsigned long              j_first;
+    unsigned long              j_last;
+
+    /*
+     * Device, blocksize and starting block offset for the location where we
+     * store the journal.
+     */
+    struct block_device        *j_dev;
+    int                        j_blocksize;
+    unsigned long              j_blk_offset;
+
+    /*
+     * Device which holds the client fs.  For internal journal this will be
+     * equal to j_dev.
+     */
+    struct block_device        *j_fs_dev;
+
+    /* Total maximum capacity of the journal region on disk. */
+    unsigned int               j_maxlen;
+
+    /*
+     * Protects the buffer lists and internal buffer state.
+     */
+    spinlock_t         j_list_lock;
+
+    /* Optional inode where we store the journal.  If present, all */
+    /* journal block numbers are mapped into this inode via */
+    /* bmap(). */
+    struct inode               *j_inode;
+
+    /*
+     * Sequence number of the oldest transaction in the log [j_state_lock]
+     */
+    tid_t                      j_tail_sequence;
+
+    /*
+     * Sequence number of the next transaction to grant [j_state_lock]
+     */
+    tid_t                      j_transaction_sequence;
+
+    /*
+     * Sequence number of the most recently committed transaction
+     * [j_state_lock].
+     */
+    tid_t                      j_commit_sequence;
+
+    /*
+     * Sequence number of the most recent transaction wanting commit
+     * [j_state_lock]
+     */
+    tid_t                      j_commit_request;
+
+    /*
+     * Journal uuid: identifies the object (filesystem, LVM volume etc)
+     * backed by this journal.  This will eventually be replaced by an array
+     * of uuids, allowing us to index multiple devices within a single
+     * journal and to perform atomic updates across them.
+     */
+    __u8                       j_uuid[16];
+
+    /* Pointer to the current commit thread for this journal */
+    struct task_struct *j_task;
+
+    /*
+     * Maximum number of metadata buffers to allow in a single compound
+     * commit transaction
+     */
+    int                        j_max_transaction_buffers;
+
+    /*
+     * What is the maximum transaction lifetime before we begin a commit?
+     */
+    unsigned long              j_commit_interval;
+
+    /* The timer used to wakeup the commit thread: */
+    struct timer_list  j_commit_timer;
+
+    /*
+     * The revoke table: maintains the list of revoked blocks in the
+     * current transaction.  [j_revoke_lock]
+     */
+    spinlock_t         j_revoke_lock;
+    struct jbd_revoke_table_s *j_revoke;
+    struct jbd_revoke_table_s *j_revoke_table[2];
+
+    /*
+     * array of bhs for journal_commit_transaction
+     */
+    struct buffer_head **j_wbuf;
+    int                        j_wbufsize;
+
+    pid_t                      j_last_sync_writer;
+
+    /*
+     * An opaque pointer to fs-private information.  ext3 puts its
+     * superblock pointer here
+     */
+    void *j_private;
+};
+
+/*
+ * Journal flag definitions
+ */
+#define JFS_UNMOUNT    0x001   /* Journal thread is being destroyed */
+#define JFS_ABORT      0x002   /* Journaling has been aborted for errors. */
+#define JFS_ACK_ERR    0x004   /* The errno in the sb has been acked */
+#define JFS_FLUSHED    0x008   /* The journal superblock has been flushed */
+#define JFS_LOADED     0x010   /* The journal superblock has been loaded */
+#define JFS_BARRIER    0x020   /* Use IDE barriers */
+
+/*
+ * Function declarations for the journaling transaction and buffer
+ * management
+ */
+
+/* Filing buffers */
+extern void journal_unfile_buffer(journal_t *, struct journal_head *);
+extern void __journal_unfile_buffer(struct journal_head *);
+extern void __journal_refile_buffer(struct journal_head *);
+extern void journal_refile_buffer(journal_t *, struct journal_head *);
+extern void __journal_file_buffer(struct journal_head *, transaction_t *, int);
+extern void __journal_free_buffer(struct journal_head *bh);
+extern void journal_file_buffer(struct journal_head *, transaction_t *, int);
+extern void __journal_clean_data_list(transaction_t *transaction);
+
+/* Log buffer allocation */
+extern struct journal_head * journal_get_descriptor_buffer(journal_t *);
+int journal_next_log_block(journal_t *, unsigned long *);
+
+/* Commit management */
+extern void journal_commit_transaction(journal_t *);
+
+/* Checkpoint list management */
+int __journal_clean_checkpoint_list(journal_t *journal);
+int __journal_remove_checkpoint(struct journal_head *);
+void __journal_insert_checkpoint(struct journal_head *, transaction_t *);
+
+/* Buffer IO */
+extern int
+    journal_write_metadata_buffer(transaction_t          *transaction,
+                                  struct journal_head  *jh_in,
+                                  struct journal_head **jh_out,
+                                  unsigned long           blocknr);
+
+/* Transaction locking */
+extern void            __wait_on_journal (journal_t *);
+
+/*
+ * Journal locking.
+ *
+ * We need to lock the journal during transaction state changes so that nobody
+ * ever tries to take a handle on the running transaction while we are in the
+ * middle of moving it to the commit phase.  j_state_lock does this.
+ *
+ * Note that the locking is completely interrupt unsafe.  We never touch
+ * journal structures from interrupts.
+ */
+
+static inline handle_t *journal_current_handle(void)
+{
+    return NULL;
+    /* return current->journal_info; */
+#ifdef _MSC_VER
+#pragma message("WARNINGS: journal_current_handle NOT implemented")
+#endif
+}
+
+/* The journaling code user interface:
+ *
+ * Create and destroy handles
+ * Register buffer modifications against the current transaction.
+ */
+
+extern handle_t *journal_start(journal_t *, int nblocks);
+extern int      journal_restart (handle_t *, int nblocks);
+extern int      journal_extend (handle_t *, int nblocks);
+extern int      journal_get_write_access(handle_t *, struct buffer_head *);
+extern int      journal_get_create_access (handle_t *, struct buffer_head *);
+extern int      journal_get_undo_access(handle_t *, struct buffer_head *);
+extern int      journal_dirty_data (handle_t *, struct buffer_head *);
+extern int      journal_dirty_metadata (handle_t *, struct buffer_head *);
+extern void     journal_release_buffer (handle_t *, struct buffer_head *);
+extern int      journal_forget (handle_t *, struct buffer_head *);
+extern void     journal_sync_buffer (struct buffer_head *);
+extern void     journal_invalidatepage(journal_t *,
+                                        struct page *, unsigned long);
+extern int      journal_try_to_free_buffers(journal_t *, struct page *, gfp_t);
+extern int      journal_stop(handle_t *);
+extern int      journal_flush (journal_t *);
+extern void     journal_lock_updates (journal_t *);
+extern void     journal_unlock_updates (journal_t *);
+
+extern journal_t * journal_init_dev(struct block_device *bdev,
+                                        struct block_device *fs_dev,
+                                        int start, int len, int bsize);
+extern journal_t * journal_init_inode (struct inode *);
+extern int        journal_update_format (journal_t *);
+extern int        journal_check_used_features
+    (journal_t *, unsigned long, unsigned long, unsigned long);
+extern int        journal_check_available_features
+    (journal_t *, unsigned long, unsigned long, unsigned long);
+extern int        journal_set_features
+    (journal_t *, unsigned long, unsigned long, unsigned long);
+extern int        journal_create     (journal_t *);
+extern int        journal_load       (journal_t *journal);
+extern void       journal_destroy    (journal_t *);
+extern int        journal_recover    (journal_t *journal);
+extern int        journal_wipe       (journal_t *, int);
+extern int        journal_skip_recovery        (journal_t *);
+extern void       journal_update_superblock    (journal_t *, int);
+void      journal_abort      (journal_t *, int);
+extern int        journal_errno      (journal_t *);
+extern void       journal_ack_err    (journal_t *);
+extern int        journal_clear_err  (journal_t *);
+extern int        journal_bmap(journal_t *, unsigned long, unsigned long *);
+extern int        journal_force_commit(journal_t *);
+
+/* added by matt */
+void journal_wipe_recovery(journal_t *journal);
+
+/*
+ * journal_head management
+ */
+struct journal_head *journal_add_journal_head(struct buffer_head *bh);
+struct journal_head *journal_grab_journal_head(struct buffer_head *bh);
+void journal_remove_journal_head(struct buffer_head *bh);
+void journal_put_journal_head(struct journal_head *jh);
+
+/*
+ * handle management
+ */
+extern struct kmem_cache *jbd_handle_cache;
+
+static inline handle_t *jbd_alloc_handle(gfp_t gfp_flags)
+{
+    return (handle_t *)kmem_cache_alloc(jbd_handle_cache, gfp_flags);
+}
+
+static inline void jbd_free_handle(handle_t *handle)
+{
+    kmem_cache_free(jbd_handle_cache, handle);
+}
+
+/* Primary revoke support */
+#define JOURNAL_REVOKE_DEFAULT_HASH 256
+extern int        journal_init_revoke(journal_t *, int);
+extern void       journal_destroy_revoke_caches(void);
+extern int        journal_init_revoke_caches(void);
+
+extern void       journal_destroy_revoke(journal_t *);
+extern int        journal_revoke (handle_t *,
+                                  unsigned long, struct buffer_head *);
+extern int        journal_cancel_revoke(handle_t *, struct journal_head *);
+extern void       journal_write_revoke_records(journal_t *, transaction_t *);
+
+/* Recovery revoke support */
+extern int     journal_set_revoke(journal_t *, unsigned long, tid_t);
+extern int     journal_test_revoke(journal_t *, unsigned long, tid_t);
+extern void    journal_clear_revoke(journal_t *);
+extern void    journal_switch_revoke_table(journal_t *journal);
+
+/*
+ * The log thread user interface:
+ *
+ * Request space in the current transaction, and force transaction commit
+ * transitions on demand.
+ */
+
+int __log_space_left(journal_t *); /* Called with journal locked */
+int log_start_commit(journal_t *journal, tid_t tid);
+int __log_start_commit(journal_t *journal, tid_t tid);
+int journal_start_commit(journal_t *journal, tid_t *tid);
+int journal_force_commit_nested(journal_t *journal);
+int log_wait_commit(journal_t *journal, tid_t tid);
+int log_do_checkpoint(journal_t *journal);
+
+void __log_wait_for_space(journal_t *journal);
+extern void    __journal_drop_transaction(journal_t *, transaction_t *);
+extern int     cleanup_journal_tail(journal_t *);
+
+/* Debugging code only: */
+
+#define jbd_ENOSYS() \
+do {                                                                      \
+       printk (KERN_ERR "JBD unimplemented function %s\n", __FUNCTION__); \
+       current->state = TASK_UNINTERRUPTIBLE;                             \
+       schedule();                                                        \
+} while (1)
+
+/*
+ * is_journal_abort
+ *
+ * Simple test wrapper function to test the JFS_ABORT state flag.  This
+ * bit, when set, indicates that we have had a fatal error somewhere,
+ * either inside the journaling layer or indicated to us by the client
+ * (eg. ext3), and that we and should not commit any further
+ * transactions.
+ */
+
+static inline int is_journal_aborted(journal_t *journal)
+{
+    return journal->j_flags & JFS_ABORT;
+}
+
+static inline int is_handle_aborted(handle_t *handle)
+{
+    if (handle->h_aborted)
+        return 1;
+    return is_journal_aborted(handle->h_transaction->t_journal);
+}
+
+static inline void journal_abort_handle(handle_t *handle)
+{
+    handle->h_aborted = 1;
+}
+
+#endif /* __KERNEL__   */
+
+/* Comparison functions for transaction IDs: perform comparisons using
+ * modulo arithmetic so that they work over sequence number wraps. */
+
+static inline int tid_gt(tid_t x, tid_t y)
+{
+    int difference = (x - y);
+    return (difference > 0);
+}
+
+static inline int tid_geq(tid_t x, tid_t y)
+{
+    int difference = (x - y);
+    return (difference >= 0);
+}
+
+extern int journal_blocks_per_page(struct inode *inode);
+
+/*
+ * Return the minimum number of blocks which must be free in the journal
+ * before a new transaction may be started.  Must be called under j_state_lock.
+ */
+static inline int jbd_space_needed(journal_t *journal)
+{
+    int nblocks = journal->j_max_transaction_buffers;
+    if (journal->j_committing_transaction)
+        nblocks += journal->j_committing_transaction->
+                   t_outstanding_credits;
+    return nblocks;
+}
+
+/*
+ * Definitions which augment the buffer_head layer
+ */
+
+/* journaling buffer types */
+#define BJ_None                0       /* Not journaled */
+#define BJ_SyncData    1       /* Normal data: flush before commit */
+#define BJ_Metadata    2       /* Normal journaled metadata */
+#define BJ_Forget      3       /* Buffer superseded by this transaction */
+#define BJ_IO          4       /* Buffer is for temporary IO use */
+#define BJ_Shadow      5       /* Buffer contents being shadowed to the log */
+#define BJ_LogCtl      6       /* Buffer contains log descriptors */
+#define BJ_Reserved    7       /* Buffer is reserved for access by journal */
+#define BJ_Locked      8       /* Locked for I/O during commit */
+#define BJ_Types       9
+
+extern int jbd_blocks_per_page(struct inode *inode);
+
+#ifdef __KERNEL__
+
+#define buffer_trace_init(bh)  do {} while (0)
+#define print_buffer_fields(bh)        do {} while (0)
+#define print_buffer_trace(bh) do {} while (0)
+#define BUFFER_TRACE(bh, info) do {} while (0)
+#define BUFFER_TRACE2(bh, bh2, info)   do {} while (0)
+#define JBUFFER_TRACE(jh, info)        do {} while (0)
+
+#endif /* __KERNEL__ */
+
+#endif /* _LINUX_JBD_H */
diff --git a/reactos/drivers/filesystems/ext2_new/inc/linux/journal-head.h b/reactos/drivers/filesystems/ext2_new/inc/linux/journal-head.h
new file mode 100644 (file)
index 0000000..7171777
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * include/linux/journal-head.h
+ *
+ * buffer_head fields for JBD
+ *
+ * 27 May 2001 Andrew Morton <akpm@digeo.com>
+ *     Created - pulled out of fs.h
+ */
+
+#ifndef JOURNAL_HEAD_H_INCLUDED
+#define JOURNAL_HEAD_H_INCLUDED
+
+typedef unsigned int           tid_t;          /* Unique transaction ID */
+typedef struct transaction_s   transaction_t;  /* Compound transaction type */
+struct buffer_head;
+
+struct journal_head {
+    /*
+     * Points back to our buffer_head. [jbd_lock_bh_journal_head()]
+     */
+    struct buffer_head *b_bh;
+
+    /*
+     * Reference count - see description in journal.c
+     * [jbd_lock_bh_journal_head()]
+     */
+    int b_jcount;
+
+    /*
+     * Journalling list for this buffer [jbd_lock_bh_state()]
+     */
+    unsigned b_jlist;
+
+    /*
+     * This flag signals the buffer has been modified by
+     * the currently running transaction
+     * [jbd_lock_bh_state()]
+     */
+    unsigned b_modified;
+
+    /*
+     * Copy of the buffer data frozen for writing to the log.
+     * [jbd_lock_bh_state()]
+     */
+    char *b_frozen_data;
+
+    /*
+     * Pointer to a saved copy of the buffer containing no uncommitted
+     * deallocation references, so that allocations can avoid overwriting
+     * uncommitted deletes. [jbd_lock_bh_state()]
+     */
+    char *b_committed_data;
+
+    /*
+     * Pointer to the compound transaction which owns this buffer's
+     * metadata: either the running transaction or the committing
+     * transaction (if there is one).  Only applies to buffers on a
+     * transaction's data or metadata journaling list.
+     * [j_list_lock] [jbd_lock_bh_state()]
+     */
+    transaction_t *b_transaction;
+
+    /*
+     * Pointer to the running compound transaction which is currently
+     * modifying the buffer's metadata, if there was already a transaction
+     * committing it when the new transaction touched it.
+     * [t_list_lock] [jbd_lock_bh_state()]
+     */
+    transaction_t *b_next_transaction;
+
+    /*
+     * Doubly-linked list of buffers on a transaction's data, metadata or
+     * forget queue. [t_list_lock] [jbd_lock_bh_state()]
+     */
+    struct journal_head *b_tnext, *b_tprev;
+
+    /*
+     * Pointer to the compound transaction against which this buffer
+     * is checkpointed.  Only dirty buffers can be checkpointed.
+     * [j_list_lock]
+     */
+    transaction_t *b_cp_transaction;
+
+    /*
+     * Doubly-linked list of buffers still remaining to be flushed
+     * before an old transaction can be checkpointed.
+     * [j_list_lock]
+     */
+    struct journal_head *b_cpnext, *b_cpprev;
+};
+
+#endif         /* JOURNAL_HEAD_H_INCLUDED */
diff --git a/reactos/drivers/filesystems/ext2_new/inc/linux/list.h b/reactos/drivers/filesystems/ext2_new/inc/linux/list.h
new file mode 100644 (file)
index 0000000..62bf07d
--- /dev/null
@@ -0,0 +1,255 @@
+#ifndef __LINUX_LIST_H__
+#define __LINUX_LIST_H__
+
+/*
+ * Simple doubly linked list implementation.
+ *
+ * Some of the internal functions ("__xxx") are useful when
+ * manipulating whole lists rather than single entries, as
+ * sometimes we already know the next/prev entries and we can
+ * generate better code by using them directly rather than
+ * using the generic single-entry routines.
+ */
+
+#define prefetch(a) ((void *)a)
+
+struct list_head {
+    struct list_head *next, *prev;
+};
+
+#define LIST_HEAD_INIT(name) { &(name), &(name) }
+
+#define LIST_HEAD(name) \
+       struct list_head name = LIST_HEAD_INIT(name)
+
+static inline void INIT_LIST_HEAD(struct list_head *list)
+{
+    list->next = list;
+    list->prev = list;
+}
+
+/*
+ * Insert a new entry between two known consecutive entries.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+static inline void __list_add(struct list_head * new,
+                              struct list_head * prev,
+                              struct list_head * next)
+{
+    next->prev = new;
+    new->next = next;
+    new->prev = prev;
+    prev->next = new;
+}
+
+/**
+ * list_add - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it after
+ *
+ * Insert a new entry after the specified head.
+ * This is good for implementing stacks.
+ */
+static inline void list_add(struct list_head *new, struct list_head *head)
+{
+    __list_add(new, head, head->next);
+}
+
+/**
+ * list_add_tail - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it before
+ *
+ * Insert a new entry before the specified head.
+ * This is useful for implementing queues.
+ */
+static inline void list_add_tail(struct list_head *new, struct list_head *head)
+{
+    __list_add(new, head->prev, head);
+}
+
+/*
+ * Delete a list entry by making the prev/next entries
+ * point to each other.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+static inline void __list_del(struct list_head * prev, struct list_head * next)
+{
+    next->prev = prev;
+    prev->next = next;
+}
+
+/**
+ * list_del - deletes entry from list.
+ * @entry: the element to delete from the list.
+ * Note: list_empty on entry does not return true after this, the entry is in an undefined state.
+ */
+static inline void list_del(struct list_head *entry)
+{
+    __list_del(entry->prev, entry->next);
+}
+
+/**
+ * list_del_init - deletes entry from list and reinitialize it.
+ * @entry: the element to delete from the list.
+ */
+static inline void list_del_init(struct list_head *entry)
+{
+    __list_del(entry->prev, entry->next);
+    INIT_LIST_HEAD(entry);
+}
+
+/**
+ * list_move - delete from one list and add as another's head
+ * @list: the entry to move
+ * @head: the head that will precede our entry
+ */
+static inline void list_move(struct list_head *list, struct list_head *head)
+{
+    __list_del(list->prev, list->next);
+    list_add(list, head);
+}
+
+/**
+ * list_move_tail - delete from one list and add as another's tail
+ * @list: the entry to move
+ * @head: the head that will follow our entry
+ */
+static inline void list_move_tail(struct list_head *list,
+                                  struct list_head *head)
+{
+    __list_del(list->prev, list->next);
+    list_add_tail(list, head);
+}
+
+/**
+ * list_empty - tests whether a list is empty
+ * @head: the list to test.
+ */
+static inline int list_empty(struct list_head *head)
+{
+    return head->next == head;
+}
+
+static inline int list_empty_careful(const struct list_head *head)
+{
+    struct list_head *next = head->next;
+    return (next == head) && (next == head->prev);
+}
+
+static inline void __list_splice(struct list_head *list,
+                                 struct list_head *head)
+{
+    struct list_head *first = list->next;
+    struct list_head *last = list->prev;
+    struct list_head *at = head->next;
+
+    first->prev = head;
+    head->next = first;
+
+    last->next = at;
+    at->prev = last;
+}
+
+/**
+ * list_splice - join two lists
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ */
+static inline void list_splice(struct list_head *list, struct list_head *head)
+{
+    if (!list_empty(list))
+        __list_splice(list, head);
+}
+
+/**
+ * list_splice_init - join two lists and reinitialise the emptied list.
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ *
+ * The list at @list is reinitialised
+ */
+static inline void list_splice_init(struct list_head *list,
+                                    struct list_head *head)
+{
+    if (!list_empty(list)) {
+        __list_splice(list, head);
+        INIT_LIST_HEAD(list);
+    }
+}
+
+/**
+ * list_entry - get the struct for this entry
+ * @ptr:       the &struct list_head pointer.
+ * @type:      the type of the struct this is embedded in.
+ * @member:    the name of the list_struct within the struct.
+ */
+#define list_entry(ptr, type, member) \
+       ((type *)((char *)(ptr)-(char *)(&((type *)0)->member)))
+
+/**
+ * list_for_each       -       iterate over a list
+ * @pos:       the &struct list_head to use as a loop counter.
+ * @head:      the head for your list.
+ */
+#define list_for_each(pos, head) \
+       for (pos = (head)->next, prefetch(pos->next); pos != (head); \
+               pos = pos->next, prefetch(pos->next))
+
+/**
+ * list_for_each_safe  -       iterate over a list safe against removal of list entry
+ * @pos:       the &struct list_head to use as a loop counter.
+ * @n:         another &struct list_head to use as temporary storage
+ * @head:      the head for your list.
+ */
+#define list_for_each_safe(pos, n, head) \
+       for (pos = (head)->next, n = pos->next; pos != (head); \
+               pos = n, n = pos->next)
+
+#ifndef list_for_each_prev
+/**
+ * list_for_each_prev  -       iterate over a list in reverse order
+ * @pos:       the &struct list_head to use as a loop counter.
+ * @head:      the head for your list.
+ */
+#define list_for_each_prev(pos, head) \
+       for (pos = (head)->prev, prefetch(pos->prev); pos != (head); \
+               pos = pos->prev, prefetch(pos->prev))
+
+#endif /* list_for_each_prev */
+
+#ifndef list_for_each_entry
+/**
+ * list_for_each_entry  -       iterate over list of given type
+ * @pos:        the type * to use as a loop counter.
+ * @head:       the head for your list.
+ * @member:     the name of the list_struct within the struct.
+ */
+#define list_for_each_entry(pos, head, type, member)           \
+        for (pos = list_entry((head)->next, type, member),     \
+                    prefetch(pos->member.next);                        \
+            &pos->member != (head);                                    \
+            pos = list_entry(pos->member.next, type, member),  \
+            prefetch(pos->member.next))
+#endif /* list_for_each_entry */
+
+#ifndef list_for_each_entry_safe
+/**
+ * list_for_each_entry_safe  -       iterate over list of given type safe against removal of list entry
+ * @pos:        the type * to use as a loop counter.
+ * @n:          another type * to use as temporary storage
+ * @head:       the head for your list.
+ * @member:     the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_safe(pos, n, head, type, member)                   \
+        for (pos = list_entry((head)->next, type, member),     \
+               n = list_entry(pos->member.next, type, member); \
+            &pos->member != (head);                                    \
+            pos = n, n = list_entry(n->member.next, type, member))
+#endif /* list_for_each_entry_safe */
+
+#endif /* __LINUX_LIST_H__ */
diff --git a/reactos/drivers/filesystems/ext2_new/inc/linux/log2.h b/reactos/drivers/filesystems/ext2_new/inc/linux/log2.h
new file mode 100644 (file)
index 0000000..f5bd56a
--- /dev/null
@@ -0,0 +1,140 @@
+/* Integer base 2 logarithm calculation
+ *
+ * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * 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.
+ */
+
+#ifndef _LINUX_LOG2_H
+#define _LINUX_LOG2_H
+
+#include <linux/types.h>
+#include <linux/bitops.h>
+
+/*
+ * deal with unrepresentable constant logarithms
+ */
+int ____ilog2_NaN(void);
+
+/*
+ * non-constant log of base 2 calculators
+ * - the arch may override these in asm/bitops.h if they can be implemented
+ *   more efficiently than using fls() and fls64()
+ * - the arch is not required to handle n==0 if implementing the fallback
+ */
+#ifndef CONFIG_ARCH_HAS_ILOG2_U32
+static inline __attribute__((const))
+int __ilog2_u32(u32 n)
+{
+    return fls(n) - 1;
+}
+#endif
+
+#ifndef CONFIG_ARCH_HAS_ILOG2_U64
+static inline __attribute__((const))
+int __ilog2_u64(u64 n)
+{
+    return fls64(n) - 1;
+}
+#endif
+
+/*
+ *  Determine whether some value is a power of two, where zero is
+ * *not* considered a power of two.
+ */
+
+static inline __attribute__((const))
+bool is_power_of_2(unsigned long n)
+{
+    return (n != 0 && ((n & (n - 1)) == 0));
+}
+
+/*
+ * round up to nearest power of two
+ */
+static inline __attribute__((const))
+unsigned long __roundup_pow_of_two(unsigned long n)
+{
+    return 1UL << fls_long(n - 1);
+}
+
+/*
+ * round down to nearest power of two
+ */
+static inline __attribute__((const))
+unsigned long __rounddown_pow_of_two(unsigned long n)
+{
+    return 1UL << (fls_long(n) - 1);
+}
+
+/**
+ * ilog2 - log of base 2 of 32-bit or a 64-bit unsigned value
+ * @n - parameter
+ *
+ * constant-capable log of base 2 calculation
+ * - this can be used to initialise global variables from constant data, hence
+ *   the massive ternary operator construction
+ *
+ * selects the appropriately-sized optimised version depending on sizeof(n)
+ */
+#define ilog2(n)                               \
+(                                              \
+       (sizeof(n) <= 4) ?                      \
+       __ilog2_u32(n) :                        \
+       __ilog2_u64(n)                          \
+ )
+
+/**
+ * roundup_pow_of_two - round the given value up to nearest power of two
+ * @n - parameter
+ *
+ * round the given value up to the nearest power of two
+ * - the result is undefined when n == 0
+ * - this can be used to initialise global variables from constant data
+ */
+#define roundup_pow_of_two(n)                  \
+(                                              \
+       __builtin_constant_p(n) ? (             \
+               (n == 1) ? 1 :                  \
+               (1UL << (ilog2((n) - 1) + 1))   \
+                                  ) :          \
+       __roundup_pow_of_two(n)                 \
+ )
+
+/**
+ * rounddown_pow_of_two - round the given value down to nearest power of two
+ * @n - parameter
+ *
+ * round the given value down to the nearest power of two
+ * - the result is undefined when n == 0
+ * - this can be used to initialise global variables from constant data
+ */
+#define rounddown_pow_of_two(n)                        \
+(                                              \
+       __builtin_constant_p(n) ? (             \
+               (n == 1) ? 0 :                  \
+               (1UL << ilog2(n))) :            \
+       __rounddown_pow_of_two(n)               \
+ )
+
+/**
+ * order_base_2 - calculate the (rounded up) base 2 order of the argument
+ * @n: parameter
+ *
+ * The first few values calculated by this routine:
+ *  ob2(0) = 0
+ *  ob2(1) = 0
+ *  ob2(2) = 1
+ *  ob2(3) = 2
+ *  ob2(4) = 2
+ *  ob2(5) = 3
+ *  ... and so on.
+ */
+
+#define order_base_2(n) ilog2(roundup_pow_of_two(n))
+
+#endif /* _LINUX_LOG2_H */
diff --git a/reactos/drivers/filesystems/ext2_new/inc/linux/module.h b/reactos/drivers/filesystems/ext2_new/inc/linux/module.h
new file mode 100644 (file)
index 0000000..c0f0d65
--- /dev/null
@@ -0,0 +1,1206 @@
+/*
+ * 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://ext2.yeah.net
+ * UPDATE HISTORY:
+ */
+
+#ifndef _EXT2_MODULE_HEADER_
+#define _EXT2_MODULE_HEADER_
+
+/* INCLUDES *************************************************************/
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/log2.h>
+#include <linux/rbtree.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 __cplusplus
+extern "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))
+
+#elif !defined(__REACTOS__)
+
+USHORT
+FASTCALL
+RtlUshortByteSwap(
+    IN USHORT Source
+);
+
+ULONG
+FASTCALL
+RtlUlongByteSwap(
+    IN ULONG Source
+);
+
+ULONGLONG
+FASTCALL
+RtlUlonglongByteSwap(
+    IN ULONGLONG Source
+);
+#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
+//
+
+
+static inline int cond_resched() {
+    return FALSE;
+}
+static inline int need_resched() {
+    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 */
+
+    spinlock_t              bd_bh_lock;    /**/
+    kmem_cache_t *          bd_bh_cache;   /* memory cache for buffer_head */
+    struct rb_root          bd_bh_root;    /* buffer_head red-black tree root */
+};
+
+//
+// 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;
+#endif
+typedef 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 {
+    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 */
+};
+
+
+/*
+ * 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);
+#endif
+void 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);
+
+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 0
+static 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 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 void
+map_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;
+NTKERNELAPI
+NTSTATUS
+ExUuidCreate(
+    OUT UUID *Uuid
+);
+
+NTKERNELAPI
+PVOID
+NTAPI
+ExAllocatePoolWithTag(
+    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
+);
+
+VOID
+Ext2FreePool(
+    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
+//
+