Whamcloud - gitweb
libext2fs: store checksum seed in superblock
[tools/e2fsprogs.git] / lib / ext2fs / ext2fs.h
index 1e07f88..c98355d 100644 (file)
@@ -39,6 +39,8 @@ extern "C" {
 #define SUPERBLOCK_OFFSET      1024
 #define SUPERBLOCK_SIZE                1024
 
+#define UUID_STR_SIZE 37
+
 /*
  * The last ext2fs revision level that this version of the library is
  * able to support.
@@ -64,12 +66,6 @@ extern "C" {
 #include <ext2fs/ext3_extents.h>
 #endif /* EXT2_FLAT_INCLUDES */
 
-#ifdef __CHECK_ENDIAN__
-#define __bitwise __attribute__((bitwise))
-#else
-#define __bitwise
-#endif
-
 typedef __u32 __bitwise                ext2_ino_t;
 typedef __u32 __bitwise                blk_t;
 typedef __u64 __bitwise                blk64_t;
@@ -191,6 +187,7 @@ typedef struct ext2_file *ext2_file_t;
 #define EXT2_FLAG_PRINT_PROGRESS       0x40000
 #define EXT2_FLAG_DIRECT_IO            0x80000
 #define EXT2_FLAG_SKIP_MMP             0x100000
+#define EXT2_FLAG_IGNORE_CSUM_ERRORS   0x200000
 
 /*
  * Special flag in the ext2 inode i_flag field that means that this is
@@ -273,6 +270,21 @@ struct struct_ext2_filsys {
         * Time at which e2fsck last updated the MMP block.
         */
        long mmp_last_written;
+
+       /* progress operation functions */
+       struct ext2fs_progress_ops *progress_ops;
+
+       /* Precomputed FS UUID checksum for seeding other checksums */
+       __u32 csum_seed;
+
+       io_channel                      journal_io;
+       char                            *journal_name;
+
+       /* New block range allocation hooks */
+       errcode_t (*new_range)(ext2_filsys fs, int flags, blk64_t goal,
+                              blk64_t len, blk64_t *pblk, blk64_t *plen);
+       void (*block_alloc_stats_range)(ext2_filsys fs, blk64_t blk, blk_t num,
+                                       int inuse);
 };
 
 #if EXT2_FLAT_INCLUDES
@@ -291,9 +303,10 @@ struct struct_ext2_filsys {
 /*
  * Return flags for the block iterator functions
  */
-#define BLOCK_CHANGED  1
-#define BLOCK_ABORT    2
-#define BLOCK_ERROR    4
+#define BLOCK_CHANGED                  1
+#define BLOCK_ABORT                    2
+#define BLOCK_ERROR                    4
+#define BLOCK_INLINE_DATA_CHANGED      8
 
 /*
  * Block interate flags
@@ -430,11 +443,14 @@ struct ext2_extent_info {
 
 #define DIRENT_FLAG_INCLUDE_EMPTY      1
 #define DIRENT_FLAG_INCLUDE_REMOVED    2
+#define DIRENT_FLAG_INCLUDE_CSUM       4
+#define DIRENT_FLAG_INCLUDE_INLINE_DATA 8
 
 #define DIRENT_DOT_FILE                1
 #define DIRENT_DOT_DOT_FILE    2
 #define DIRENT_OTHER_FILE      3
 #define DIRENT_DELETED_FILE    4
+#define DIRENT_CHECKSUM                5
 
 /*
  * Inode scan definitions
@@ -449,6 +465,7 @@ typedef struct ext2_struct_inode_scan *ext2_inode_scan;
 #define EXT2_SF_BAD_EXTRA_BYTES        0x0004
 #define EXT2_SF_SKIP_MISSING_ITABLE    0x0008
 #define EXT2_SF_DO_LAZY                0x0010
+#define EXT2_SF_WARN_GARBAGE_INODES    0x0020
 
 /*
  * ext2fs_check_if_mounted flags
@@ -516,6 +533,8 @@ typedef struct ext2_icount *ext2_icount_t;
  */
 #define BMAP_ALLOC     0x0001
 #define BMAP_SET       0x0002
+#define BMAP_UNINIT    0x0004
+#define BMAP_ZERO      0x0008
 
 /*
  * Returned flags from ext2fs_bmap
@@ -535,13 +554,6 @@ typedef struct ext2_icount *ext2_icount_t;
 #define EXT2_CHECK_MAGIC(struct, code) \
          if ((struct)->magic != (code)) return (code)
 
-
-/*
- * For ext2 compression support
- */
-#define EXT2FS_COMPRESSED_BLKADDR ((blk_t) -1)
-#define HOLE_BLKADDR(_b) ((_b) == 0 || (_b) == EXT2FS_COMPRESSED_BLKADDR)
-
 /*
  * Features supported by this version of the library
  */
@@ -550,36 +562,27 @@ typedef struct ext2_icount *ext2_icount_t;
                                         EXT3_FEATURE_COMPAT_HAS_JOURNAL|\
                                         EXT2_FEATURE_COMPAT_RESIZE_INODE|\
                                         EXT2_FEATURE_COMPAT_DIR_INDEX|\
-                                        EXT2_FEATURE_COMPAT_EXT_ATTR)
-
-/* This #ifdef is temporary until compression is fully supported */
-#ifdef ENABLE_COMPRESSION
-#ifndef I_KNOW_THAT_COMPRESSION_IS_EXPERIMENTAL
-/* If the below warning bugs you, then have
-   `CPPFLAGS=-DI_KNOW_THAT_COMPRESSION_IS_EXPERIMENTAL' in your
-   environment at configure time. */
- #warning "Compression support is experimental"
-#endif
-#define EXT2_LIB_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE|\
-                                        EXT2_FEATURE_INCOMPAT_COMPRESSION|\
-                                        EXT3_FEATURE_INCOMPAT_JOURNAL_DEV|\
-                                        EXT2_FEATURE_INCOMPAT_META_BG|\
-                                        EXT3_FEATURE_INCOMPAT_RECOVER|\
-                                        EXT3_FEATURE_INCOMPAT_EXTENTS|\
-                                        EXT4_FEATURE_INCOMPAT_FLEX_BG|\
-                                        EXT4_FEATURE_INCOMPAT_MMP|\
-                                        EXT4_FEATURE_INCOMPAT_64BIT)
+                                        EXT2_FEATURE_COMPAT_EXT_ATTR|\
+                                        EXT4_FEATURE_COMPAT_SPARSE_SUPER2)
+
+#ifdef CONFIG_MMP
+#define EXT4_LIB_INCOMPAT_MMP          EXT4_FEATURE_INCOMPAT_MMP
 #else
+#define EXT4_LIB_INCOMPAT_MMP          (0)
+#endif
+
 #define EXT2_LIB_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE|\
                                         EXT3_FEATURE_INCOMPAT_JOURNAL_DEV|\
                                         EXT2_FEATURE_INCOMPAT_META_BG|\
                                         EXT3_FEATURE_INCOMPAT_RECOVER|\
                                         EXT3_FEATURE_INCOMPAT_EXTENTS|\
                                         EXT4_FEATURE_INCOMPAT_FLEX_BG|\
-                                        EXT4_FEATURE_INCOMPAT_MMP|\
-                                        EXT4_FEATURE_INCOMPAT_64BIT)
-#endif
-#ifdef CONFIG_QUOTA
+                                        EXT4_LIB_INCOMPAT_MMP|\
+                                        EXT4_FEATURE_INCOMPAT_64BIT|\
+                                        EXT4_FEATURE_INCOMPAT_INLINE_DATA|\
+                                        EXT4_FEATURE_INCOMPAT_ENCRYPT|\
+                                        EXT4_FEATURE_INCOMPAT_CSUM_SEED)
+
 #define EXT2_LIB_FEATURE_RO_COMPAT_SUPP        (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER|\
                                         EXT4_FEATURE_RO_COMPAT_HUGE_FILE|\
                                         EXT2_FEATURE_RO_COMPAT_LARGE_FILE|\
@@ -587,16 +590,10 @@ typedef struct ext2_icount *ext2_icount_t;
                                         EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE|\
                                         EXT4_FEATURE_RO_COMPAT_GDT_CSUM|\
                                         EXT4_FEATURE_RO_COMPAT_BIGALLOC|\
-                                        EXT4_FEATURE_RO_COMPAT_QUOTA)
-#else
-#define EXT2_LIB_FEATURE_RO_COMPAT_SUPP        (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER|\
-                                        EXT4_FEATURE_RO_COMPAT_HUGE_FILE|\
-                                        EXT2_FEATURE_RO_COMPAT_LARGE_FILE|\
-                                        EXT4_FEATURE_RO_COMPAT_DIR_NLINK|\
-                                        EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE|\
-                                        EXT4_FEATURE_RO_COMPAT_GDT_CSUM|\
-                                        EXT4_FEATURE_RO_COMPAT_BIGALLOC)
-#endif
+                                        EXT4_FEATURE_RO_COMPAT_QUOTA|\
+                                        EXT4_FEATURE_RO_COMPAT_METADATA_CSUM|\
+                                        EXT4_FEATURE_RO_COMPAT_READONLY |\
+                                        EXT4_FEATURE_RO_COMPAT_PROJECT)
 
 /*
  * These features are only allowed if EXT2_FLAG_SOFTSUPP_FEATURES is passed
@@ -629,8 +626,20 @@ typedef struct stat ext2fs_struct_stat;
 #define EXT2_FLAG_FLUSH_NO_SYNC          1
 
 /*
+ * Modify and iterate extended attributes
+ */
+struct ext2_xattr_handle;
+#define XATTR_ABORT    1
+#define XATTR_CHANGED  2
+
+/*
  * function prototypes
  */
+static inline int ext2fs_has_group_desc_csum(ext2_filsys fs)
+{
+       return ext2fs_has_feature_metadata_csum(fs->super) ||
+              ext2fs_has_feature_gdt_csum(fs->super);
+}
 
 /* The LARGE_FILE feature should be set if we have stored files 2GB+ in size */
 static inline int ext2fs_needs_large_file_feature(unsigned long long file_size)
@@ -664,6 +673,29 @@ extern void ext2fs_set_alloc_block_callback(ext2_filsys fs,
                                            errcode_t (**old)(ext2_filsys fs,
                                                              blk64_t goal,
                                                              blk64_t *ret));
+blk64_t ext2fs_find_inode_goal(ext2_filsys fs, ext2_ino_t ino,
+                              struct ext2_inode *inode, blk64_t lblk);
+extern void ext2fs_set_new_range_callback(ext2_filsys fs,
+       errcode_t (*func)(ext2_filsys fs, int flags, blk64_t goal,
+                              blk64_t len, blk64_t *pblk, blk64_t *plen),
+       errcode_t (**old)(ext2_filsys fs, int flags, blk64_t goal,
+                              blk64_t len, blk64_t *pblk, blk64_t *plen));
+extern void ext2fs_set_block_alloc_stats_range_callback(ext2_filsys fs,
+       void (*func)(ext2_filsys fs, blk64_t blk,
+                                   blk_t num, int inuse),
+       void (**old)(ext2_filsys fs, blk64_t blk,
+                                   blk_t num, int inuse));
+#define EXT2_NEWRANGE_FIXED_GOAL       (0x1)
+#define EXT2_NEWRANGE_MIN_LENGTH       (0x2)
+#define EXT2_NEWRANGE_ALL_FLAGS                (0x3)
+errcode_t ext2fs_new_range(ext2_filsys fs, int flags, blk64_t goal,
+                          blk64_t len, ext2fs_block_bitmap map, blk64_t *pblk,
+                          blk64_t *plen);
+#define EXT2_ALLOCRANGE_FIXED_GOAL     (0x1)
+#define EXT2_ALLOCRANGE_ZERO_BLOCKS    (0x2)
+#define EXT2_ALLOCRANGE_ALL_FLAGS      (0x3)
+errcode_t ext2fs_alloc_range(ext2_filsys fs, int flags, blk64_t goal,
+                            blk_t len, blk64_t *ret);
 
 /* alloc_sb.c */
 extern int ext2fs_reserve_super_and_bgd(ext2_filsys fs,
@@ -683,6 +715,8 @@ void ext2fs_inode_alloc_stats2(ext2_filsys fs, ext2_ino_t ino,
                               int inuse, int isdir);
 void ext2fs_block_alloc_stats(ext2_filsys fs, blk_t blk, int inuse);
 void ext2fs_block_alloc_stats2(ext2_filsys fs, blk64_t blk, int inuse);
+void ext2fs_block_alloc_stats_range(ext2_filsys fs, blk64_t blk,
+                                   blk_t num, int inuse);
 
 /* alloc_tables.c */
 extern errcode_t ext2fs_allocate_tables(ext2_filsys fs);
@@ -804,6 +838,8 @@ extern errcode_t ext2fs_get_block_bitmap_range2(ext2fs_block_bitmap bmap,
                                         void *out);
 
 /* blknum.c */
+extern __u32 ext2fs_inode_bitmap_checksum(ext2_filsys fs, dgrp_t group);
+extern __u32 ext2fs_block_bitmap_checksum(ext2_filsys fs, dgrp_t group);
 extern dgrp_t ext2fs_group_of_blk2(ext2_filsys fs, blk64_t);
 extern blk64_t ext2fs_group_first_block2(ext2_filsys fs, dgrp_t group);
 extern blk64_t ext2fs_group_last_block2(ext2_filsys fs, dgrp_t group);
@@ -831,9 +867,11 @@ extern void ext2fs_free_blocks_count_add(struct ext2_super_block *super,
 extern struct ext2_group_desc *ext2fs_group_desc(ext2_filsys fs,
                                          struct opaque_ext2_group_desc *gdp,
                                          dgrp_t group);
+extern blk64_t ext2fs_block_bitmap_csum(ext2_filsys fs, dgrp_t group);
 extern blk64_t ext2fs_block_bitmap_loc(ext2_filsys fs, dgrp_t group);
 extern void ext2fs_block_bitmap_loc_set(ext2_filsys fs, dgrp_t group,
                                        blk64_t blk);
+extern __u32 ext2fs_inode_bitmap_csum(ext2_filsys fs, dgrp_t group);
 extern blk64_t ext2fs_inode_bitmap_loc(ext2_filsys fs, dgrp_t group);
 extern void ext2fs_inode_bitmap_loc_set(ext2_filsys fs, dgrp_t group,
                                        blk64_t blk);
@@ -863,6 +901,8 @@ extern blk64_t ext2fs_file_acl_block(ext2_filsys fs,
                                     const struct ext2_inode *inode);
 extern void ext2fs_file_acl_block_set(ext2_filsys fs,
                                      struct ext2_inode *inode, blk64_t blk);
+extern errcode_t ext2fs_inode_size_set(ext2_filsys fs, struct ext2_inode *inode,
+                                      ext2_off64_t size);
 
 /* block.c */
 extern errcode_t ext2fs_block_iterate(ext2_filsys fs,
@@ -924,6 +964,7 @@ extern errcode_t ext2fs_check_desc(ext2_filsys fs);
 /* closefs.c */
 extern errcode_t ext2fs_close(ext2_filsys fs);
 extern errcode_t ext2fs_close2(ext2_filsys fs, int flags);
+extern errcode_t ext2fs_close_free(ext2_filsys *fs);
 extern errcode_t ext2fs_flush(ext2_filsys fs);
 extern errcode_t ext2fs_flush2(ext2_filsys fs, int flags);
 extern int ext2fs_bg_has_super(ext2_filsys fs, dgrp_t group_block);
@@ -942,18 +983,66 @@ extern int ext2fs_super_and_bgd_loc(ext2_filsys fs,
 extern void ext2fs_update_dynamic_rev(ext2_filsys fs);
 
 /* crc32c.c */
-extern __u32 ext2fs_crc32c_be(__u32 crc, unsigned char const *p, size_t len);
+extern __u32 ext2fs_crc32_be(__u32 crc, unsigned char const *p, size_t len);
 extern __u32 ext2fs_crc32c_le(__u32 crc, unsigned char const *p, size_t len);
 
 /* csum.c */
+extern void ext2fs_init_csum_seed(ext2_filsys fs);
+extern errcode_t ext2fs_mmp_csum_set(ext2_filsys fs, struct mmp_struct *mmp);
+extern int ext2fs_mmp_csum_verify(ext2_filsys, struct mmp_struct *mmp);
+extern int ext2fs_verify_csum_type(ext2_filsys fs, struct ext2_super_block *sb);
+extern errcode_t ext2fs_superblock_csum_set(ext2_filsys fs,
+                                           struct ext2_super_block *sb);
+extern int ext2fs_superblock_csum_verify(ext2_filsys fs,
+                                        struct ext2_super_block *sb);
+extern errcode_t ext2fs_ext_attr_block_csum_set(ext2_filsys fs,
+                                       ext2_ino_t inum, blk64_t block,
+                                       struct ext2_ext_attr_header *hdr);
+extern int ext2fs_ext_attr_block_csum_verify(ext2_filsys fs, ext2_ino_t inum,
+                                            blk64_t block,
+                                            struct ext2_ext_attr_header *hdr);
+#define EXT2_DIRENT_TAIL(block, blocksize) \
+       ((struct ext2_dir_entry_tail *)(((char *)(block)) + \
+       (blocksize) - sizeof(struct ext2_dir_entry_tail)))
+
+extern void ext2fs_initialize_dirent_tail(ext2_filsys fs,
+                                         struct ext2_dir_entry_tail *t);
+extern int ext2fs_dirent_has_tail(ext2_filsys fs,
+                                 struct ext2_dir_entry *dirent);
+extern int ext2fs_dirent_csum_verify(ext2_filsys fs, ext2_ino_t inum,
+                                    struct ext2_dir_entry *dirent);
+extern int ext2fs_dir_block_csum_verify(ext2_filsys fs, ext2_ino_t inum,
+                                       struct ext2_dir_entry *dirent);
+extern errcode_t ext2fs_dir_block_csum_set(ext2_filsys fs, ext2_ino_t inum,
+                                          struct ext2_dir_entry *dirent);
+extern errcode_t ext2fs_get_dx_countlimit(ext2_filsys fs,
+                                         struct ext2_dir_entry *dirent,
+                                         struct ext2_dx_countlimit **cc,
+                                         int *offset);
+extern errcode_t ext2fs_extent_block_csum_set(ext2_filsys fs,
+                                             ext2_ino_t inum,
+                                             struct ext3_extent_header *eh);
+extern int ext2fs_extent_block_csum_verify(ext2_filsys fs,
+                                          ext2_ino_t inum,
+                                          struct ext3_extent_header *eh);
+extern errcode_t ext2fs_block_bitmap_csum_set(ext2_filsys fs, dgrp_t group,
+                                             char *bitmap, int size);
+extern int ext2fs_block_bitmap_csum_verify(ext2_filsys fs, dgrp_t group,
+                                          char *bitmap, int size);
+extern errcode_t ext2fs_inode_bitmap_csum_set(ext2_filsys fs, dgrp_t group,
+                                             char *bitmap, int size);
+extern int ext2fs_inode_bitmap_csum_verify(ext2_filsys fs, dgrp_t group,
+                                          char *bitmap, int size);
+extern errcode_t ext2fs_inode_csum_set(ext2_filsys fs, ext2_ino_t inum,
+                                      struct ext2_inode_large *inode);
+extern int ext2fs_inode_csum_verify(ext2_filsys fs, ext2_ino_t inum,
+                                   struct ext2_inode_large *inode);
 extern void ext2fs_group_desc_csum_set(ext2_filsys fs, dgrp_t group);
 extern int ext2fs_group_desc_csum_verify(ext2_filsys fs, dgrp_t group);
 extern errcode_t ext2fs_set_gdt_csum(ext2_filsys fs);
 extern __u16 ext2fs_group_desc_csum(ext2_filsys fs, dgrp_t group);
 
 /* dblist.c */
-
-extern errcode_t ext2fs_get_num_dirs(ext2_filsys fs, ext2_ino_t *ret_num_dirs);
 extern errcode_t ext2fs_init_dblist(ext2_filsys fs, ext2_dblist *ret_dblist);
 extern errcode_t ext2fs_add_dir_block(ext2_dblist dblist, ext2_ino_t ino,
                                      blk_t blk, int blockcnt);
@@ -968,11 +1057,17 @@ extern void ext2fs_dblist_sort2(ext2_dblist dblist,
 extern errcode_t ext2fs_dblist_iterate(ext2_dblist dblist,
        int (*func)(ext2_filsys fs, struct ext2_db_entry *db_info,
                    void        *priv_data),
-       void *priv_data);
+       void *priv_data);
 extern errcode_t ext2fs_dblist_iterate2(ext2_dblist dblist,
        int (*func)(ext2_filsys fs, struct ext2_db_entry2 *db_info,
                    void        *priv_data),
-       void *priv_data);
+       void *priv_data);
+extern errcode_t ext2fs_dblist_iterate3(ext2_dblist dblist,
+       int (*func)(ext2_filsys fs, struct ext2_db_entry2 *db_info,
+                   void        *priv_data),
+       unsigned long long start,
+       unsigned long long count,
+       void *priv_data);
 extern errcode_t ext2fs_set_dir_block(ext2_dblist dblist, ext2_ino_t ino,
                                      blk_t blk, int blockcnt);
 extern errcode_t ext2fs_set_dir_block2(ext2_dblist dblist, ext2_ino_t ino,
@@ -1001,6 +1096,13 @@ extern errcode_t
                                              void      *priv_data),
                                  void *priv_data);
 
+#if 0
+/* digest_encode.c */
+#define EXT2FS_DIGEST_SIZE EXT2FS_SHA256_LENGTH
+extern int ext2fs_digest_encode(const char *src, int len, char *dst);
+extern int ext2fs_digest_decode(const char *src, int len, char *dst);
+#endif
+
 /* dirblock.c */
 extern errcode_t ext2fs_read_dir_block(ext2_filsys fs, blk_t block,
                                       void *buf);
@@ -1008,12 +1110,16 @@ extern errcode_t ext2fs_read_dir_block2(ext2_filsys fs, blk_t block,
                                        void *buf, int flags);
 extern errcode_t ext2fs_read_dir_block3(ext2_filsys fs, blk64_t block,
                                        void *buf, int flags);
+extern errcode_t ext2fs_read_dir_block4(ext2_filsys fs, blk64_t block,
+                                       void *buf, int flags, ext2_ino_t ino);
 extern errcode_t ext2fs_write_dir_block(ext2_filsys fs, blk_t block,
                                        void *buf);
 extern errcode_t ext2fs_write_dir_block2(ext2_filsys fs, blk_t block,
                                         void *buf, int flags);
 extern errcode_t ext2fs_write_dir_block3(ext2_filsys fs, blk64_t block,
                                         void *buf, int flags);
+extern errcode_t ext2fs_write_dir_block4(ext2_filsys fs, blk64_t block,
+                                        void *buf, int flags, ext2_ino_t ino);
 
 /* dirhash.c */
 extern errcode_t ext2fs_dirhash(int version, const char *name, int len,
@@ -1064,16 +1170,46 @@ extern __u32 ext2fs_ext_attr_hash_entry(struct ext2_ext_attr_entry *entry,
 extern errcode_t ext2fs_read_ext_attr(ext2_filsys fs, blk_t block, void *buf);
 extern errcode_t ext2fs_read_ext_attr2(ext2_filsys fs, blk64_t block,
                                       void *buf);
+extern errcode_t ext2fs_read_ext_attr3(ext2_filsys fs, blk64_t block,
+                                      void *buf, ext2_ino_t inum);
 extern errcode_t ext2fs_write_ext_attr(ext2_filsys fs, blk_t block,
                                       void *buf);
 extern errcode_t ext2fs_write_ext_attr2(ext2_filsys fs, blk64_t block,
                                       void *buf);
+extern errcode_t ext2fs_write_ext_attr3(ext2_filsys fs, blk64_t block,
+                                      void *buf, ext2_ino_t inum);
 extern errcode_t ext2fs_adjust_ea_refcount(ext2_filsys fs, blk_t blk,
                                           char *block_buf,
                                           int adjust, __u32 *newcount);
 extern errcode_t ext2fs_adjust_ea_refcount2(ext2_filsys fs, blk64_t blk,
                                           char *block_buf,
                                           int adjust, __u32 *newcount);
+extern errcode_t ext2fs_adjust_ea_refcount3(ext2_filsys fs, blk64_t blk,
+                                          char *block_buf,
+                                          int adjust, __u32 *newcount,
+                                          ext2_ino_t inum);
+errcode_t ext2fs_xattrs_write(struct ext2_xattr_handle *handle);
+errcode_t ext2fs_xattrs_read(struct ext2_xattr_handle *handle);
+errcode_t ext2fs_xattrs_iterate(struct ext2_xattr_handle *h,
+                               int (*func)(char *name, char *value,
+                                           size_t value_len, void *data),
+                               void *data);
+errcode_t ext2fs_xattr_get(struct ext2_xattr_handle *h, const char *key,
+                          void **value, size_t *value_len);
+errcode_t ext2fs_xattr_set(struct ext2_xattr_handle *handle,
+                          const char *key,
+                          const void *value,
+                          size_t value_len);
+errcode_t ext2fs_xattr_remove(struct ext2_xattr_handle *handle,
+                             const char *key);
+errcode_t ext2fs_xattrs_open(ext2_filsys fs, ext2_ino_t ino,
+                            struct ext2_xattr_handle **handle);
+errcode_t ext2fs_xattrs_close(struct ext2_xattr_handle **handle);
+errcode_t ext2fs_free_ext_attr(ext2_filsys fs, ext2_ino_t ino,
+                              struct ext2_inode_large *inode);
+errcode_t ext2fs_xattrs_count(struct ext2_xattr_handle *handle, size_t *count);
+errcode_t ext2fs_xattr_inode_max_size(ext2_filsys fs, ext2_ino_t ino,
+                                     size_t *size);
 
 /* extent.c */
 extern errcode_t ext2fs_extent_header_verify(void *ptr, int size);
@@ -1101,6 +1237,17 @@ extern errcode_t ext2fs_extent_goto(ext2_extent_handle_t handle,
 extern errcode_t ext2fs_extent_goto2(ext2_extent_handle_t handle,
                                     int leaf_level, blk64_t blk);
 extern errcode_t ext2fs_extent_fix_parents(ext2_extent_handle_t handle);
+size_t ext2fs_max_extent_depth(ext2_extent_handle_t handle);
+
+/* fallocate.c */
+#define EXT2_FALLOCATE_ZERO_BLOCKS     (0x1)
+#define EXT2_FALLOCATE_FORCE_INIT      (0x2)
+#define EXT2_FALLOCATE_FORCE_UNINIT    (0x4)
+#define EXT2_FALLOCATE_INIT_BEYOND_EOF (0x8)
+#define EXT2_FALLOCATE_ALL_FLAGS       (0xF)
+errcode_t ext2fs_fallocate(ext2_filsys fs, int flags, ext2_ino_t ino,
+                          struct ext2_inode *inode, blk64_t goal,
+                          blk64_t start, blk64_t len);
 
 /* fileio.c */
 extern errcode_t ext2fs_file_open2(ext2_filsys fs, ext2_ino_t ino,
@@ -1182,10 +1329,6 @@ extern errcode_t ext2fs_find_first_set_generic_bitmap(ext2fs_generic_bitmap bitm
                                                       __u32 *out);
 
 /* gen_bitmap64.c */
-
-/* Generate and print bitmap usage statistics */
-#define BMAP_STATS
-
 void ext2fs_free_generic_bmap(ext2fs_generic_bitmap bmap);
 errcode_t ext2fs_alloc_generic_bmap(ext2_filsys fs, errcode_t magic,
                                    int type, __u64 start, __u64 end,
@@ -1214,6 +1357,9 @@ errcode_t ext2fs_set_generic_bmap_range(ext2fs_generic_bitmap bmap,
 errcode_t ext2fs_convert_subcluster_bitmap(ext2_filsys fs,
                                           ext2fs_block_bitmap *bitmap);
 
+/* get_num_dirs.c */
+extern errcode_t ext2fs_get_num_dirs(ext2_filsys fs, ext2_ino_t *ret_num_dirs);
+
 /* getsize.c */
 extern errcode_t ext2fs_get_device_size(const char *file, int blocksize,
                                        blk_t *retblocks);
@@ -1275,12 +1421,27 @@ errcode_t ext2fs_icount_validate(ext2_icount_t icount, FILE *);
 extern errcode_t ext2fs_get_memalign(unsigned long size,
                                     unsigned long align, void *ptr);
 
+/* inline_data.c */
+extern errcode_t ext2fs_inline_data_init(ext2_filsys fs, ext2_ino_t ino);
+extern errcode_t ext2fs_inline_data_size(ext2_filsys fs, ext2_ino_t ino,
+                                        size_t *size);
+extern errcode_t ext2fs_inline_data_get(ext2_filsys fs, ext2_ino_t ino,
+                                       struct ext2_inode *inode,
+                                       void *buf, size_t *size);
+extern errcode_t ext2fs_inline_data_set(ext2_filsys fs, ext2_ino_t ino,
+                                       struct ext2_inode *inode,
+                                       void *buf, size_t size);
+
 /* inode.c */
+extern errcode_t ext2fs_create_inode_cache(ext2_filsys fs,
+                                          unsigned int cache_size);
+extern void ext2fs_free_inode_cache(struct ext2_inode_cache *icache);
 extern errcode_t ext2fs_flush_icache(ext2_filsys fs);
 extern errcode_t ext2fs_get_next_inode_full(ext2_inode_scan scan,
                                            ext2_ino_t *ino,
                                            struct ext2_inode *inode,
                                            int bufsize);
+#define EXT2_INODE_SCAN_DEFAULT_BUFFER_BLOCKS  8
 extern errcode_t ext2fs_open_inode_scan(ext2_filsys fs, int buffer_blocks,
                                  ext2_inode_scan *ret_scan);
 extern void ext2fs_close_inode_scan(ext2_inode_scan scan);
@@ -1351,6 +1512,8 @@ int ext2fs_native_flag(void);
 /* newdir.c */
 extern errcode_t ext2fs_new_dir_block(ext2_filsys fs, ext2_ino_t dir_ino,
                                ext2_ino_t parent_ino, char **block);
+extern errcode_t ext2fs_new_dir_inline_data(ext2_filsys fs, ext2_ino_t dir_ino,
+                               ext2_ino_t parent_ino, __u32 *iblock);
 
 /* mkdir.c */
 extern errcode_t ext2fs_mkdir(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t inum,
@@ -1368,7 +1531,10 @@ extern errcode_t ext2fs_add_journal_device(ext2_filsys fs,
                                           ext2_filsys journal_dev);
 extern errcode_t ext2fs_add_journal_inode(ext2_filsys fs, blk_t num_blocks,
                                          int flags);
+extern errcode_t ext2fs_add_journal_inode2(ext2_filsys fs, blk_t num_blocks,
+                                          blk64_t goal, int flags);
 extern int ext2fs_default_journal_size(__u64 num_blocks);
+extern int ext2fs_journal_sb_start(int blocksize);
 
 /* openfs.c */
 extern errcode_t ext2fs_open(const char *name, int flags, int superblock,
@@ -1403,7 +1569,7 @@ errcode_t ext2fs_unlink(ext2_filsys fs, ext2_ino_t dir, const char *name,
 
 /* symlink.c */
 errcode_t ext2fs_symlink(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t ino,
-                        const char *name, char *target);
+                        const char *name, const char *target);
 
 /* mmp.c */
 errcode_t ext2fs_mmp_read(ext2_filsys fs, blk64_t mmp_blk, void *buf);
@@ -1412,6 +1578,7 @@ errcode_t ext2fs_mmp_clear(ext2_filsys fs);
 errcode_t ext2fs_mmp_init(ext2_filsys fs);
 errcode_t ext2fs_mmp_start(ext2_filsys fs);
 errcode_t ext2fs_mmp_update(ext2_filsys fs);
+errcode_t ext2fs_mmp_update2(ext2_filsys fs, int immediately);
 errcode_t ext2fs_mmp_stop(ext2_filsys fs);
 unsigned ext2fs_mmp_new_seq(void);
 
@@ -1435,7 +1602,25 @@ extern errcode_t ext2fs_read_bb_FILE(ext2_filsys fs, FILE *f,
 /* res_gdt.c */
 extern errcode_t ext2fs_create_resize_inode(ext2_filsys fs);
 
+/*sha256.c */
+#define EXT2FS_SHA256_LENGTH 32
+#if 0
+extern void ext2fs_sha256(const unsigned char *in, unsigned long in_size,
+                  unsigned char out[EXT2FS_SHA256_LENGTH]);
+#endif
+
+/* sha512.c */
+#define EXT2FS_SHA512_LENGTH 64
+extern void ext2fs_sha512(const unsigned char *in, unsigned long in_size,
+                         unsigned char out[EXT2FS_SHA512_LENGTH]);
+
 /* swapfs.c */
+extern errcode_t ext2fs_dirent_swab_in2(ext2_filsys fs, char *buf, size_t size,
+                                       int flags);
+extern errcode_t ext2fs_dirent_swab_in(ext2_filsys fs, char *buf, int flags);
+extern errcode_t ext2fs_dirent_swab_out2(ext2_filsys fs, char *buf, size_t size,
+                                        int flags);
+extern errcode_t ext2fs_dirent_swab_out(ext2_filsys fs, char *buf, int flags);
 extern void ext2fs_swap_ext_attr(char *to, char *from, int bufsize,
                                 int has_header);
 extern void ext2fs_swap_ext_attr_header(struct ext2_ext_attr_header *to_header,
@@ -1502,6 +1687,11 @@ extern blk_t ext2fs_inode_data_blocks(ext2_filsys fs,
                                      struct ext2_inode *inode);
 extern unsigned int ext2fs_div_ceil(unsigned int a, unsigned int b);
 extern __u64 ext2fs_div64_ceil(__u64 a, __u64 b);
+extern int ext2fs_dirent_name_len(const struct ext2_dir_entry *entry);
+extern void ext2fs_dirent_set_name_len(struct ext2_dir_entry *entry, int len);
+extern int ext2fs_dirent_file_type(const struct ext2_dir_entry *entry);
+extern void ext2fs_dirent_set_file_type(struct ext2_dir_entry *entry, int type);
+
 #endif
 
 /*
@@ -1555,7 +1745,7 @@ _INLINE_ errcode_t ext2fs_get_memzero(unsigned long size, void *ptr)
 
 _INLINE_ errcode_t ext2fs_get_array(unsigned long count, unsigned long size, void *ptr)
 {
-       if (count && (-1UL)/count<size)
+       if (count && (~0UL)/count < size)
                return EXT2_ET_NO_MEMORY;
        return ext2fs_get_mem(count*size, ptr);
 }
@@ -1565,7 +1755,7 @@ _INLINE_ errcode_t ext2fs_get_arrayzero(unsigned long count,
 {
        void *pp;
 
-       if (count && (-1UL)/count<size)
+       if (count && (~0UL)/count < size)
                return EXT2_ET_NO_MEMORY;
        pp = calloc(count, size);
        if (!pp)
@@ -1741,6 +1931,26 @@ _INLINE_ __u64 ext2fs_div64_ceil(__u64 a, __u64 b)
        return ((a - 1) / b) + 1;
 }
 
+_INLINE_ int ext2fs_dirent_name_len(const struct ext2_dir_entry *entry)
+{
+       return entry->name_len & 0xff;
+}
+
+_INLINE_ void ext2fs_dirent_set_name_len(struct ext2_dir_entry *entry, int len)
+{
+       entry->name_len = (entry->name_len & 0xff00) | (len & 0xff);
+}
+
+_INLINE_ int ext2fs_dirent_file_type(const struct ext2_dir_entry *entry)
+{
+       return entry->name_len >> 8;
+}
+
+_INLINE_ void ext2fs_dirent_set_file_type(struct ext2_dir_entry *entry, int type)
+{
+       entry->name_len = (entry->name_len & 0xff) | (type << 8);
+}
+
 #undef _INLINE_
 #endif