X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lib%2Fext2fs%2Fext2fs.h;h=dd6404e361565eb007da3caa5c0658785d10822c;hb=9224d817b9aa844b748296e9b6fea0b9aa6af83e;hp=08f1946389e161469f17c3ca2a3aadf29771f118;hpb=7becb2065ffd5c4b403546d577c2421b4a840c3c;p=tools%2Fe2fsprogs.git diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h index 08f1946..dd6404e 100644 --- a/lib/ext2fs/ext2fs.h +++ b/lib/ext2fs/ext2fs.h @@ -29,10 +29,6 @@ extern "C" { #define NO_INLINE_FUNCS #endif -#ifndef _XOPEN_SOURCE -#define _XOPEN_SOURCE 600 /* for posix_memalign() */ -#endif - /* * Where the master copy of the superblock is located, and how big * superblocks are supposed to be. We define SUPERBLOCK_SIZE because @@ -57,16 +53,6 @@ extern "C" { #include #include #include -#include -#include -#include - -#ifndef __USE_XOPEN2K -/* If the "#define _XOPEN_SOURCE 600" didn't succeed in declaring - * posix_memalign(), maybe due to or included beforej - * _XOPEN_SOURCE, declare it here to avoid compiler warnings. */ -extern int posix_memalign(void **__memptr, size_t __alignment, size_t __size); -#endif #if EXT2_FLAT_INCLUDES #include "e2_types.h" @@ -78,14 +64,20 @@ extern int posix_memalign(void **__memptr, size_t __alignment, size_t __size); #include #endif /* EXT2_FLAT_INCLUDES */ -typedef __u32 ext2_ino_t; -typedef __u32 blk_t; -typedef __u64 blk64_t; -typedef __u32 dgrp_t; -typedef __u32 ext2_off_t; -typedef __u64 ext2_off64_t; -typedef __s64 e2_blkcnt_t; -typedef __u32 ext2_dirhash_t; +#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; +typedef __u32 __bitwise dgrp_t; +typedef __u32 __bitwise ext2_off_t; +typedef __u64 __bitwise ext2_off64_t; +typedef __s64 __bitwise e2_blkcnt_t; +typedef __u32 __bitwise ext2_dirhash_t; #if EXT2_FLAT_INCLUDES #include "com_err.h" @@ -199,6 +191,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 @@ -211,6 +204,7 @@ typedef struct ext2_file *ext2_file_t; */ #define EXT2_MKJOURNAL_V1_SUPER 0x0000001 /* create V1 superblock (deprecated) */ #define EXT2_MKJOURNAL_LAZYINIT 0x0000002 /* don't zero journal inode before use*/ +#define EXT2_MKJOURNAL_NO_MNT_CHECK 0x0000004 /* don't check mount status */ struct opaque_ext2_group_desc; @@ -244,10 +238,12 @@ struct struct_ext2_filsys { __u32 umask; time_t now; int cluster_ratio_bits; + __u16 default_bitmap_type; + __u16 pad; /* * Reserved for future expansion */ - __u32 reserved[6]; + __u32 reserved[5]; /* * Reserved for the use of the calling application. @@ -261,6 +257,13 @@ struct struct_ext2_filsys { io_channel image_io; /* + * More callback functions + */ + errcode_t (*get_alloc_block)(ext2_filsys fs, blk64_t goal, + blk64_t *ret); + void (*block_alloc_stats)(ext2_filsys fs, blk64_t blk, int inuse); + + /* * Buffers for Multiple mount protection(MMP) block. */ void *mmp_buf; @@ -272,12 +275,11 @@ struct struct_ext2_filsys { */ long mmp_last_written; - /* - * More callback functions - */ - errcode_t (*get_alloc_block)(ext2_filsys fs, blk64_t goal, - blk64_t *ret); - void (*block_alloc_stats)(ext2_filsys fs, blk64_t blk, int inuse); + /* progress operation functions */ + struct ext2fs_progress_ops *progress_ops; + + /* Precomputed FS UUID checksum for seeding other checksums */ + __u32 csum_seed; }; #if EXT2_FLAT_INCLUDES @@ -287,6 +289,13 @@ struct struct_ext2_filsys { #endif /* + * 64-bit bitmap backend types + */ +#define EXT2FS_BMAP64_BITARRAY 1 +#define EXT2FS_BMAP64_RBTREE 2 +#define EXT2FS_BMAP64_AUTODIR 3 + +/* * Return flags for the block iterator functions */ #define BLOCK_CHANGED 1 @@ -428,11 +437,13 @@ struct ext2_extent_info { #define DIRENT_FLAG_INCLUDE_EMPTY 1 #define DIRENT_FLAG_INCLUDE_REMOVED 2 +#define DIRENT_FLAG_INCLUDE_CSUM 4 #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 @@ -548,7 +559,8 @@ 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) + EXT2_FEATURE_COMPAT_EXT_ATTR|\ + EXT4_FEATURE_COMPAT_SPARSE_SUPER2) /* This #ifdef is temporary until compression is fully supported */ #ifdef ENABLE_COMPRESSION @@ -558,26 +570,33 @@ typedef struct ext2_icount *ext2_icount_t; 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) +#define EXT2_LIB_INCOMPAT_COMPRESSION EXT2_FEATURE_INCOMPAT_COMPRESSION +#else +#define EXT2_LIB_INCOMPAT_COMPRESSION (0) +#endif + +#ifdef CONFIG_MMP +#define EXT4_LIB_INCOMPAT_MMP EXT4_FEATURE_INCOMPAT_MMP +#else +#define EXT4_LIB_INCOMPAT_MMP (0) +#endif + +#ifdef CONFIG_QUOTA +#define EXT4_LIB_RO_COMPAT_QUOTA EXT4_FEATURE_RO_COMPAT_QUOTA #else +#define EXT4_LIB_RO_COMPAT_QUOTA (0) +#endif + #define EXT2_LIB_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE|\ + EXT2_LIB_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_LIB_INCOMPAT_MMP|\ EXT4_FEATURE_INCOMPAT_64BIT) -#endif -#ifdef CONFIG_QUOTA + #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|\ @@ -585,23 +604,15 @@ 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_LIB_RO_COMPAT_QUOTA|\ + EXT4_FEATURE_RO_COMPAT_METADATA_CSUM) /* * These features are only allowed if EXT2_FLAG_SOFTSUPP_FEATURES is passed * to ext2fs_openfs() */ -#define EXT2_LIB_SOFTSUPP_INCOMPAT (0) -#define EXT2_LIB_SOFTSUPP_RO_COMPAT (EXT4_FEATURE_RO_COMPAT_BIGALLOC) +#define EXT2_LIB_SOFTSUPP_INCOMPAT (EXT4_FEATURE_INCOMPAT_INLINE_DATA) +#define EXT2_LIB_SOFTSUPP_RO_COMPAT (EXT4_FEATURE_RO_COMPAT_REPLICA) /* Translate a block number to a cluster number */ @@ -627,8 +638,27 @@ 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 EXT2_HAS_RO_COMPAT_FEATURE(fs->super, + EXT4_FEATURE_RO_COMPAT_GDT_CSUM | + EXT4_FEATURE_RO_COMPAT_METADATA_CSUM); +} + +/* 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) +{ + return file_size >= 0x80000000ULL; +} /* alloc.c */ extern errcode_t ext2fs_new_inode(ext2_filsys fs, ext2_ino_t dir, int mode, @@ -675,6 +705,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); @@ -796,6 +828,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); @@ -823,9 +857,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); @@ -898,6 +934,9 @@ extern errcode_t ext2fs_bmap2(ext2_filsys fs, ext2_ino_t ino, struct ext2_inode *inode, char *block_buf, int bmap_flags, blk64_t block, int *ret_flags, blk64_t *phys_blk); +errcode_t ext2fs_map_cluster_block(ext2_filsys fs, ext2_ino_t ino, + struct ext2_inode *inode, blk64_t lblk, + blk64_t *pblk); #if 0 /* bmove.c */ @@ -915,7 +954,7 @@ extern errcode_t ext2fs_close(ext2_filsys fs); extern errcode_t ext2fs_close2(ext2_filsys fs, int flags); 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, int group_block); +extern int ext2fs_bg_has_super(ext2_filsys fs, dgrp_t group_block); extern errcode_t ext2fs_super_and_bgd_loc2(ext2_filsys fs, dgrp_t group, blk64_t *ret_super_blk, @@ -931,17 +970,65 @@ 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 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); @@ -996,12 +1083,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, @@ -1052,16 +1143,44 @@ 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); +size_t ext2fs_xattrs_count(struct ext2_xattr_handle *handle); /* extent.c */ extern errcode_t ext2fs_extent_header_verify(void *ptr, int size); @@ -1073,6 +1192,7 @@ extern errcode_t ext2fs_extent_open2(ext2_filsys fs, ext2_ino_t ino, extern void ext2fs_extent_free(ext2_extent_handle_t handle); extern errcode_t ext2fs_extent_get(ext2_extent_handle_t handle, int flags, struct ext2fs_extent *extent); +extern errcode_t ext2fs_extent_node_split(ext2_extent_handle_t handle); extern errcode_t ext2fs_extent_replace(ext2_extent_handle_t handle, int flags, struct ext2fs_extent *extent); extern errcode_t ext2fs_extent_insert(ext2_extent_handle_t handle, int flags, @@ -1085,6 +1205,9 @@ extern errcode_t ext2fs_extent_get_info(ext2_extent_handle_t handle, struct ext2_extent_info *info); extern errcode_t ext2fs_extent_goto(ext2_extent_handle_t handle, blk64_t blk); +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); /* fileio.c */ extern errcode_t ext2fs_file_open2(ext2_filsys fs, ext2_ino_t ino, @@ -1094,6 +1217,7 @@ extern errcode_t ext2fs_file_open(ext2_filsys fs, ext2_ino_t ino, int flags, ext2_file_t *ret); extern ext2_filsys ext2fs_file_get_fs(ext2_file_t file); struct ext2_inode *ext2fs_file_get_inode(ext2_file_t file); +extern ext2_ino_t ext2fs_file_get_inode_num(ext2_file_t file); extern errcode_t ext2fs_file_close(ext2_file_t file); extern errcode_t ext2fs_file_flush(ext2_file_t file); extern errcode_t ext2fs_file_read(ext2_file_t file, void *buf, @@ -1157,6 +1281,12 @@ extern errcode_t ext2fs_set_generic_bitmap_range(ext2fs_generic_bitmap bmap, errcode_t magic, __u32 start, __u32 num, void *in); +extern errcode_t ext2fs_find_first_zero_generic_bitmap(ext2fs_generic_bitmap bitmap, + __u32 start, __u32 end, + __u32 *out); +extern errcode_t ext2fs_find_first_set_generic_bitmap(ext2fs_generic_bitmap bitmap, + __u32 start, __u32 end, + __u32 *out); /* gen_bitmap64.c */ void ext2fs_free_generic_bmap(ext2fs_generic_bitmap bmap); @@ -1187,6 +1317,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); @@ -1194,6 +1327,7 @@ extern errcode_t ext2fs_get_device_size2(const char *file, int blocksize, blk64_t *retblocks); /* getsectsize.c */ +extern int ext2fs_get_dio_alignment(int fd); errcode_t ext2fs_get_device_sectsize(const char *file, int *sectsize); errcode_t ext2fs_get_device_phys_sectsize(const char *file, int *sectsize); @@ -1242,7 +1376,13 @@ extern errcode_t ext2fs_icount_store(ext2_icount_t icount, ext2_ino_t ino, extern ext2_ino_t ext2fs_get_icount_size(ext2_icount_t icount); errcode_t ext2fs_icount_validate(ext2_icount_t icount, FILE *); +/* inline.c */ + +extern errcode_t ext2fs_get_memalign(unsigned long size, + unsigned long align, void *ptr); + /* inode.c */ +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, @@ -1293,6 +1433,10 @@ extern errcode_t ext2fs_check_mount_point(const char *device, int *mount_flags, char *mtpt, int mtlen); /* punch.c */ +/* + * NOTE: This function removes from an inode the blocks "start", "end", and + * every block in between. + */ extern errcode_t ext2fs_punch(ext2_filsys fs, ext2_ino_t ino, struct ext2_inode *inode, char *block_buf, blk64_t start, @@ -1331,6 +1475,8 @@ 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); /* openfs.c */ @@ -1341,6 +1487,11 @@ extern errcode_t ext2fs_open2(const char *name, const char *io_options, int flags, int superblock, unsigned int block_size, io_manager manager, ext2_filsys *ret_fs); +/* + * The dgrp_t argument to these two functions is not actually a group number + * but a block number offset within a group table! Convert with the formula + * (group_number / groups_per_block). + */ extern blk64_t ext2fs_descriptor_block_loc2(ext2_filsys fs, blk64_t group_block, dgrp_t i); extern blk_t ext2fs_descriptor_block_loc(ext2_filsys fs, blk_t group_block, @@ -1359,6 +1510,10 @@ errcode_t ext2fs_link(ext2_filsys fs, ext2_ino_t dir, const char *name, errcode_t ext2fs_unlink(ext2_filsys fs, ext2_ino_t dir, const char *name, ext2_ino_t ino, int flags); +/* symlink.c */ +errcode_t ext2fs_symlink(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t ino, + const char *name, char *target); + /* mmp.c */ errcode_t ext2fs_mmp_read(ext2_filsys fs, blk64_t mmp_blk, void *buf); errcode_t ext2fs_mmp_write(ext2_filsys fs, blk64_t mmp_blk, void *buf); @@ -1366,6 +1521,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); @@ -1390,6 +1546,8 @@ extern errcode_t ext2fs_read_bb_FILE(ext2_filsys fs, FILE *f, extern errcode_t ext2fs_create_resize_inode(ext2_filsys fs); /* swapfs.c */ +extern errcode_t ext2fs_dirent_swab_in(ext2_filsys fs, char *buf, 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, @@ -1406,6 +1564,11 @@ extern void ext2fs_swap_inode(ext2_filsys fs,struct ext2_inode *t, struct ext2_inode *f, int hostorder); extern void ext2fs_swap_mmp(struct mmp_struct *mmp); +/* unix_io.c */ +extern int ext2fs_open_file(const char *pathname, int flags, mode_t mode); +extern int ext2fs_stat(const char *path, ext2fs_struct_stat *buf); +extern int ext2fs_fstat(int fd, ext2fs_struct_stat *buf); + /* valid_blk.c */ extern int ext2fs_inode_has_valid_blocks(struct ext2_inode *inode); extern int ext2fs_inode_has_valid_blocks2(ext2_filsys fs, @@ -1423,9 +1586,9 @@ extern errcode_t ext2fs_write_bb_FILE(ext2_badblocks_list bb_list, /* inline functions */ +#ifdef NO_INLINE_FUNCS +extern void ext2fs_init_csum_seed(ext2_filsys fs); extern errcode_t ext2fs_get_mem(unsigned long size, void *ptr); -extern errcode_t ext2fs_get_memalign(unsigned long size, - unsigned long align, void *ptr); extern errcode_t ext2fs_get_memzero(unsigned long size, void *ptr); extern errcode_t ext2fs_get_array(unsigned long count, unsigned long size, void *ptr); @@ -1444,17 +1607,15 @@ extern void ext2fs_mark_ib_dirty(ext2_filsys fs); extern void ext2fs_mark_bb_dirty(ext2_filsys fs); extern int ext2fs_test_ib_dirty(ext2_filsys fs); extern int ext2fs_test_bb_dirty(ext2_filsys fs); -extern int ext2fs_group_of_blk(ext2_filsys fs, blk_t blk); -extern int ext2fs_group_of_ino(ext2_filsys fs, ext2_ino_t ino); +extern dgrp_t ext2fs_group_of_blk(ext2_filsys fs, blk_t blk); +extern dgrp_t ext2fs_group_of_ino(ext2_filsys fs, ext2_ino_t ino); extern blk_t ext2fs_group_first_block(ext2_filsys fs, dgrp_t group); extern blk_t ext2fs_group_last_block(ext2_filsys fs, dgrp_t group); 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_open_file(const char *pathname, int flags, mode_t mode); -extern int ext2fs_stat(const char *path, ext2fs_struct_stat *buf); -extern int ext2fs_fstat(int fd, ext2fs_struct_stat *buf); +#endif /* * The actual inlined functions definitions themselves... @@ -1466,17 +1627,31 @@ extern int ext2fs_fstat(int fd, ext2fs_struct_stat *buf); #ifdef INCLUDE_INLINE_FUNCS #define _INLINE_ extern #else +#if (__STDC_VERSION__ >= 199901L) +#define _INLINE_ inline +#else #ifdef __GNUC__ #define _INLINE_ extern __inline__ #else /* For Watcom C */ #define _INLINE_ extern inline +#endif /* __GNUC__ */ +#endif /* __STDC_VERSION__ >= 199901L */ #endif -#endif + +_INLINE_ void ext2fs_init_csum_seed(ext2_filsys fs) +{ + if (!EXT2_HAS_RO_COMPAT_FEATURE(fs->super, + EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) + return; + + fs->csum_seed = ext2fs_crc32c_le(~0, fs->super->s_uuid, + sizeof(fs->super->s_uuid)); +} #ifndef EXT2_CUSTOM_MEMORY_ROUTINES #include /* - * Allocate memory + * Allocate memory. The 'ptr' arg must point to a pointer. */ _INLINE_ errcode_t ext2fs_get_mem(unsigned long size, void *ptr) { @@ -1523,7 +1698,7 @@ _INLINE_ errcode_t ext2fs_get_arrayzero(unsigned long count, } /* - * Free memory + * Free memory. The 'ptr' arg must point to a pointer. */ _INLINE_ errcode_t ext2fs_free_mem(void *ptr) { @@ -1537,7 +1712,7 @@ _INLINE_ errcode_t ext2fs_free_mem(void *ptr) } /* - * Resize memory + * Resize memory. The 'ptr' arg must point to a pointer. */ _INLINE_ errcode_t ext2fs_resize_mem(unsigned long EXT2FS_ATTR((unused)) old_size, unsigned long size, void *ptr) @@ -1638,14 +1813,14 @@ _INLINE_ int ext2fs_test_bb_dirty(ext2_filsys fs) /* * Return the group # of a block */ -_INLINE_ int ext2fs_group_of_blk(ext2_filsys fs, blk_t blk) +_INLINE_ dgrp_t ext2fs_group_of_blk(ext2_filsys fs, blk_t blk) { return ext2fs_group_of_blk2(fs, blk); } /* * Return the group # of an inode number */ -_INLINE_ int ext2fs_group_of_ino(ext2_filsys fs, ext2_ino_t ino) +_INLINE_ dgrp_t ext2fs_group_of_ino(ext2_filsys fs, ext2_ino_t ino) { return (ino - 1) / fs->super->s_inodes_per_group; } @@ -1655,7 +1830,7 @@ _INLINE_ int ext2fs_group_of_ino(ext2_filsys fs, ext2_ino_t ino) */ _INLINE_ blk_t ext2fs_group_first_block(ext2_filsys fs, dgrp_t group) { - return ext2fs_group_first_block2(fs, group); + return (blk_t) ext2fs_group_first_block2(fs, group); } /* @@ -1663,13 +1838,13 @@ _INLINE_ blk_t ext2fs_group_first_block(ext2_filsys fs, dgrp_t group) */ _INLINE_ blk_t ext2fs_group_last_block(ext2_filsys fs, dgrp_t group) { - return ext2fs_group_last_block2(fs, group); + return (blk_t) ext2fs_group_last_block2(fs, group); } _INLINE_ blk_t ext2fs_inode_data_blocks(ext2_filsys fs, struct ext2_inode *inode) { - return ext2fs_inode_data_blocks2(fs, inode); + return (blk_t) ext2fs_inode_data_blocks2(fs, inode); } /* @@ -1689,38 +1864,24 @@ _INLINE_ __u64 ext2fs_div64_ceil(__u64 a, __u64 b) return ((a - 1) / b) + 1; } -_INLINE_ int ext2fs_open_file(const char *pathname, int flags, mode_t mode) +_INLINE_ int ext2fs_dirent_name_len(const struct ext2_dir_entry *entry) { - va_list args; + return entry->name_len & 0xff; +} - if (mode) -#if defined(HAVE_OPEN64) && !defined(__OSX_AVAILABLE_BUT_DEPRECATED) - return open64(pathname, flags, mode); - else - return open64(pathname, flags); -#else - return open(pathname, flags, mode); - else - return open(pathname, flags); -#endif +_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_stat(const char *path, ext2fs_struct_stat *buf) +_INLINE_ int ext2fs_dirent_file_type(const struct ext2_dir_entry *entry) { -#if defined(HAVE_FSTAT64) && !defined(__OSX_AVAILABLE_BUT_DEPRECATED) - return stat64(path, buf); -#else - return stat(path, buf); -#endif + return entry->name_len >> 8; } -_INLINE_ int ext2fs_fstat(int fd, ext2fs_struct_stat *buf) +_INLINE_ void ext2fs_dirent_set_file_type(struct ext2_dir_entry *entry, int type) { -#if defined(HAVE_FSTAT64) && !defined(__OSX_AVAILABLE_BUT_DEPRECATED) - return fstat64(fd, buf); -#else - return fstat(fd, buf); -#endif + entry->name_len = (entry->name_len & 0xff) | (type << 8); } #undef _INLINE_