#define EXT2FS_ATTR(x)
#endif
+#ifndef __nonstring
+#ifdef __has_attribute
+#if __has_attribute(__nonstring__)
+#define __nonstring __attribute__((__nonstring__))
+#else
+#define __nonstring
+#endif /* __has_attribute(__nonstring__) */
+#else
+# define __nonstring
+#endif /* __has_attribute */
+#endif /* __nonstring */
+
#ifdef CONFIG_TDB
#define EXT2FS_NO_TDB_UNUSED
#else
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 __s32 __bitwise ext2_off_t;
+typedef __s64 __bitwise ext2_off64_t;
typedef __s64 __bitwise e2_blkcnt_t;
typedef __u32 __bitwise ext2_dirhash_t;
#define EXT2_FLAG_IGNORE_SB_ERRORS 0x800000
#define EXT2_FLAG_BBITMAP_TAIL_PROBLEM 0x1000000
#define EXT2_FLAG_IBITMAP_TAIL_PROBLEM 0x2000000
+#define EXT2_FLAG_THREADS 0x4000000
+#define EXT2_FLAG_IGNORE_SWAP_DIRENT 0x8000000
/*
* Special flag in the ext2 inode i_flag field that means that this is
#define EXT2_MKJOURNAL_LAZYINIT 0x0000002 /* don't zero journal inode before use*/
#define EXT2_MKJOURNAL_NO_MNT_CHECK 0x0000004 /* don't check mount status */
+/*
+ * Normal journal area size to fast commit area size ratio. This is used to
+ * set default size of fast commit area.
+ */
+#define EXT2_JOURNAL_TO_FC_BLKS_RATIO 64
+
struct blk_alloc_ctx;
struct opaque_ext2_group_desc;
time_t now;
int cluster_ratio_bits;
__u16 default_bitmap_type;
- __u16 pad;
+ __u16 fs_num_threads;
/*
* Reserved for future expansion
*/
#define BLOCK_INLINE_DATA_CHANGED 8
/*
- * Block interate flags
+ * Block iterate flags
*
- * BLOCK_FLAG_APPEND, or BLOCK_FLAG_HOLE, indicates that the interator
+ * BLOCK_FLAG_APPEND, or BLOCK_FLAG_HOLE, indicates that the iterator
* function should be called on blocks where the block number is zero.
* This is used by ext2fs_expand_dir() to be able to add a new block
* to an inode. It can also be used for programs that want to be able
#define EXT2_MF_READONLY 4
#define EXT2_MF_SWAP 8
#define EXT2_MF_BUSY 16
+#define EXT2_MF_EXTFS 32
/*
* Ext2/linux mode flags. We define them here so that we don't need
if ((struct)->magic != (code)) return (code)
/*
+ * Flags for returning status of ext2fs_expand_extra_isize()
+ */
+#define EXT2_EXPAND_EISIZE_UNSAFE 0x0001
+#define EXT2_EXPAND_EISIZE_NEW_BLOCK 0x0002
+#define EXT2_EXPAND_EISIZE_NOSPC 0x0004
+
+/*
* Features supported by this version of the library
*/
#define EXT2_LIB_FEATURE_COMPAT_SUPP (EXT2_FEATURE_COMPAT_DIR_PREALLOC|\
EXT2_FEATURE_COMPAT_EXT_ATTR|\
EXT4_FEATURE_COMPAT_SPARSE_SUPER2|\
EXT4_FEATURE_COMPAT_FAST_COMMIT|\
- EXT4_FEATURE_COMPAT_STABLE_INODES)
+ EXT4_FEATURE_COMPAT_STABLE_INODES|\
+ EXT4_FEATURE_COMPAT_ORPHAN_FILE)
#ifdef CONFIG_MMP
#define EXT4_LIB_INCOMPAT_MMP EXT4_FEATURE_INCOMPAT_MMP
EXT3_FEATURE_INCOMPAT_EXTENTS|\
EXT4_FEATURE_INCOMPAT_FLEX_BG|\
EXT4_FEATURE_INCOMPAT_EA_INODE|\
+ EXT4_FEATURE_INCOMPAT_DIRDATA|\
EXT4_LIB_INCOMPAT_MMP|\
EXT4_FEATURE_INCOMPAT_64BIT|\
EXT4_FEATURE_INCOMPAT_INLINE_DATA|\
EXT4_FEATURE_RO_COMPAT_READONLY |\
EXT4_FEATURE_RO_COMPAT_PROJECT |\
EXT4_FEATURE_RO_COMPAT_SHARED_BLOCKS |\
- EXT4_FEATURE_RO_COMPAT_VERITY)
+ EXT4_FEATURE_RO_COMPAT_VERITY |\
+ EXT4_FEATURE_RO_COMPAT_ORPHAN_PRESENT)
/*
* These features are only allowed if EXT2_FLAG_SOFTSUPP_FEATURES is passed
#define XATTR_CHANGED 2
/*
+ * flags for ext2fs_rw_bitmaps()
+ */
+#define EXT2FS_BITMAPS_WRITE 0x0001
+#define EXT2FS_BITMAPS_BLOCK 0x0002
+#define EXT2FS_BITMAPS_INODE 0x0004
+#define EXT2FS_BITMAPS_VALID_FLAGS 0x0007
+
+/*
* function prototypes
*/
static inline int ext2fs_has_group_desc_csum(ext2_filsys fs)
extern int ext2fs_reserve_super_and_bgd(ext2_filsys fs,
dgrp_t group,
ext2fs_block_bitmap bmap);
+extern errcode_t ext2fs_reserve_super_and_bgd2(ext2_filsys fs,
+ dgrp_t group,
+ ext2fs_block_bitmap bmap,
+ blk_t *desc_blocks);
extern void ext2fs_set_block_alloc_stats_callback(ext2_filsys fs,
void (*func)(ext2_filsys fs,
blk64_t blk,
extern void ext2fs_badblocks_list_iterate_end(ext2_badblocks_iterate iter);
extern errcode_t ext2fs_badblocks_copy(ext2_badblocks_list src,
ext2_badblocks_list *dest);
+extern errcode_t ext2fs_badblocks_merge(ext2_badblocks_list src,
+ ext2_badblocks_list dest);
extern int ext2fs_badblocks_equal(ext2_badblocks_list bb1,
ext2_badblocks_list bb2);
extern int ext2fs_u32_list_count(ext2_u32_list bb);
extern void ext2fs_free_inode_bitmap(ext2fs_inode_bitmap bitmap);
extern errcode_t ext2fs_copy_bitmap(ext2fs_generic_bitmap src,
ext2fs_generic_bitmap *dest);
-extern errcode_t ext2fs_write_inode_bitmap(ext2_filsys fs);
-extern errcode_t ext2fs_write_block_bitmap (ext2_filsys fs);
-extern errcode_t ext2fs_read_inode_bitmap (ext2_filsys fs);
-extern errcode_t ext2fs_read_block_bitmap(ext2_filsys fs);
+errcode_t ext2fs_merge_bitmap(ext2fs_generic_bitmap src,
+ ext2fs_generic_bitmap dest,
+ ext2fs_generic_bitmap dup,
+ ext2fs_generic_bitmap dup_allowed);
extern errcode_t ext2fs_allocate_block_bitmap(ext2_filsys fs,
const char *descr,
ext2fs_block_bitmap *ret);
blk64_t end, blk64_t *oend);
extern void ext2fs_clear_inode_bitmap(ext2fs_inode_bitmap bitmap);
extern void ext2fs_clear_block_bitmap(ext2fs_block_bitmap bitmap);
-extern errcode_t ext2fs_read_bitmaps(ext2_filsys fs);
-extern errcode_t ext2fs_write_bitmaps(ext2_filsys fs);
extern errcode_t ext2fs_resize_inode_bitmap(__u32 new_end, __u32 new_real_end,
ext2fs_inode_bitmap bmap);
extern errcode_t ext2fs_resize_inode_bitmap2(__u64 new_end,
extern blk64_t ext2fs_inode_data_blocks2(ext2_filsys fs,
struct ext2_inode *inode);
extern blk64_t ext2fs_inode_i_blocks(ext2_filsys fs,
- struct ext2_inode *inode);
+ struct ext2_inode *inode);
+extern blk64_t ext2fs_get_stat_i_blocks(ext2_filsys fs,
+ struct ext2_inode *inode);
extern blk64_t ext2fs_blocks_count(struct ext2_super_block *super);
extern void ext2fs_blocks_count_set(struct ext2_super_block *super,
blk64_t blk);
blk_t blk, int blockcnt);
extern errcode_t ext2fs_add_dir_block2(ext2_dblist dblist, ext2_ino_t ino,
blk64_t blk, e2_blkcnt_t blockcnt);
+extern errcode_t ext2fs_merge_dblist(ext2_dblist src, ext2_dblist dest);
extern void ext2fs_dblist_sort(ext2_dblist dblist,
EXT2_QSORT_TYPE (*sortfunc)(const void *,
const void *));
extern errcode_t ext2fs_expand_dir(ext2_filsys fs, ext2_ino_t dir);
/* ext_attr.c */
+extern errcode_t ext2fs_attr_get(ext2_filsys fs, struct ext2_inode *inode,
+ int name_index, const char *name, char *buffer,
+ size_t buffer_size, int *easize);
+
extern __u32 ext2fs_ext_attr_hash_entry(struct ext2_ext_attr_entry *entry,
void *data);
+extern __u32 ext2fs_ext_attr_hash_entry_signed(struct ext2_ext_attr_entry *entry,
+ void *data);
extern errcode_t ext2fs_ext_attr_hash_entry2(ext2_filsys fs,
struct ext2_ext_attr_entry *entry,
void *data, __u32 *hash);
+extern errcode_t ext2fs_ext_attr_hash_entry3(ext2_filsys fs,
+ struct ext2_ext_attr_entry *entry,
+ void *data, __u32 *hash,
+ __u32 *signed_hash);
+int ext2fs_attr_get_next_attr(struct ext2_ext_attr_entry *entry, int name_index,
+ char *buffer, int buffer_size, int start);
+errcode_t ext2fs_attr_set(ext2_filsys fs, ext2_ino_t ino,
+ struct ext2_inode *inode,
+ int name_index, const char *name, const char *value,
+ int value_len, int flags);
+extern errcode_t ext2fs_expand_extra_isize(ext2_filsys fs, ext2_ino_t ino,
+ struct ext2_inode_large *inode,
+ int new_extra_isize, int *ret,
+ int *needed_size);
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);
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_read_inode(struct ext2_xattr_handle *handle,
+ struct ext2_inode_large *inode);
errcode_t ext2fs_xattrs_iterate(struct ext2_xattr_handle *h,
int (*func)(char *name, char *value,
- size_t value_len, void *data),
+ size_t value_len,
+ ext2_ino_t inode_num, void *data),
void *data);
errcode_t ext2fs_xattr_get(struct ext2_xattr_handle *h, const char *key,
void **value, size_t *value_len);
extern size_t ext2fs_max_extent_depth(ext2_extent_handle_t handle);
extern errcode_t ext2fs_fix_extents_checksums(ext2_filsys fs, ext2_ino_t ino,
struct ext2_inode *inode);
+extern errcode_t ext2fs_count_blocks(ext2_filsys fs, ext2_ino_t ino,
+ struct ext2_inode *inode, blk64_t *ret_count);
+extern errcode_t ext2fs_decode_extent(struct ext2fs_extent *to, void *from,
+ int len);
/* fallocate.c */
#define EXT2_FALLOCATE_ZERO_BLOCKS (0x1)
errcode_t ext2fs_resize_generic_bmap(ext2fs_generic_bitmap bmap,
__u64 new_end,
__u64 new_real_end);
+errcode_t ext2fs_merge_generic_bmap(ext2fs_generic_bitmap gen_src,
+ ext2fs_generic_bitmap gen_dest,
+ ext2fs_generic_bitmap gen_dup,
+ ext2fs_generic_bitmap dup_allowed);
errcode_t ext2fs_compare_generic_bmap(errcode_t neq,
ext2fs_generic_bitmap bm1,
ext2fs_generic_bitmap bm2);
void *in);
errcode_t ext2fs_convert_subcluster_bitmap(ext2_filsys fs,
ext2fs_block_bitmap *bitmap);
+errcode_t ext2fs_count_used_clusters(ext2_filsys fs, blk64_t start,
+ blk64_t end, blk64_t *out);
+errcode_t ext2fs_count_used_blocks(ext2_filsys fs, blk64_t start,
+ blk64_t end, blk64_t *out);
+extern unsigned int ext2fs_list_backups(ext2_filsys fs, unsigned int *three,
+ unsigned int *five, unsigned int *seven);
/* get_num_dirs.c */
extern errcode_t ext2fs_get_num_dirs(ext2_filsys fs, ext2_ino_t *ret_num_dirs);
extern errcode_t ext2fs_initialize(const char *name, int flags,
struct ext2_super_block *param,
io_manager manager, ext2_filsys *ret_fs);
+extern errcode_t ext2fs_calculate_summary_stats(ext2_filsys fs, int super_only);
+extern void ext2fs_set_iops_group(ext2_filsys fs, blk64_t *array, int count);
+extern void ext2fs_clear_iops_group(ext2_filsys fs, blk64_t *array, int count);
/* icount.c */
extern void ext2fs_free_icount(ext2_icount_t icount);
+extern int ext2fs_icount_is_set(ext2_icount_t icount, ext2_ino_t ino);
extern errcode_t ext2fs_create_icount_tdb(ext2_filsys fs, char *tdb_dir,
int flags, ext2_icount_t *ret);
extern errcode_t ext2fs_create_icount2(ext2_filsys fs, int flags,
__u16 *ret);
extern errcode_t ext2fs_icount_store(ext2_icount_t icount, ext2_ino_t ino,
__u16 count);
+extern errcode_t ext2fs_icount_merge(ext2_icount_t src, ext2_icount_t dest);
extern ext2_ino_t ext2fs_get_icount_size(ext2_icount_t icount);
errcode_t ext2fs_icount_validate(ext2_icount_t icount, FILE *);
/* nls_utf8.c */
extern const struct ext2fs_nls_table *ext2fs_load_nls_table(int encoding);
+extern int ext2fs_check_encoded_name(const struct ext2fs_nls_table *table,
+ char *s, size_t len, char **pos);
+extern int ext2fs_casefold_cmp(const struct ext2fs_nls_table *table,
+ const unsigned char *str1, size_t len1,
+ const unsigned char *str2, size_t len2);
/* mkdir.c */
extern errcode_t ext2fs_mkdir(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t inum,
const char *name);
/* mkjournal.c */
+struct ext2fs_journal_params {
+ blk_t num_journal_blocks;
+ blk_t num_fc_blocks;
+};
+extern errcode_t ext2fs_get_journal_params(
+ struct ext2fs_journal_params *params, ext2_filsys fs);
extern errcode_t ext2fs_zero_blocks(ext2_filsys fs, blk_t blk, int num,
blk_t *ret_blk, int *ret_count);
extern errcode_t ext2fs_zero_blocks2(ext2_filsys fs, blk64_t blk, int num,
extern errcode_t ext2fs_create_journal_superblock(ext2_filsys fs,
__u32 num_blocks, int flags,
char **ret_jsb);
+extern errcode_t ext2fs_create_journal_superblock2(ext2_filsys fs,
+ struct ext2fs_journal_params *params,
+ int flags, char **ret_jsb);
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 errcode_t ext2fs_add_journal_inode3(ext2_filsys fs,
+ struct ext2fs_journal_params *params,
+ blk64_t goal, int flags);
extern int ext2fs_default_journal_size(__u64 num_blocks);
extern int ext2fs_journal_sb_start(int blocksize);
int flags, int superblock,
unsigned int block_size, io_manager manager,
ext2_filsys *ret_fs);
+errcode_t ext2fs_open_channel(ext2_filsys fs, const char *io_options,
+ io_manager manager, int flags,
+ int blocksize);
/*
* 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
errcode_t ext2fs_set_data_io(ext2_filsys fs, io_channel new_io);
errcode_t ext2fs_rewrite_to_io(ext2_filsys fs, io_channel new_io);
+/* orphan.c */
+extern errcode_t ext2fs_create_orphan_file(ext2_filsys fs, blk_t num_blocks);
+extern errcode_t ext2fs_truncate_orphan_file(ext2_filsys fs);
+extern e2_blkcnt_t ext2fs_default_orphan_file_blocks(ext2_filsys fs);
+extern __u32 ext2fs_do_orphan_file_block_csum(ext2_filsys fs, ext2_ino_t ino,
+ __u32 gen, blk64_t blk,
+ char *buf);
+extern errcode_t ext2fs_orphan_file_block_csum_set(ext2_filsys fs,
+ ext2_ino_t ino, blk64_t blk,
+ char *buf);
+extern int ext2fs_orphan_file_block_csum_verify(ext2_filsys fs, ext2_ino_t ino,
+ blk64_t blk, char *buf);
+
/* get_pathname.c */
extern errcode_t ext2fs_get_pathname(ext2_filsys fs, ext2_ino_t dir, ext2_ino_t ino,
char **name);
/* link.c */
+#define EXT2FS_UNLINK_FORCE 0x1 /* Forcefully unlink even if
+ * the inode number doesn't
+ * match the dirent
+ */
errcode_t ext2fs_link(ext2_filsys fs, ext2_ino_t dir, const char *name,
ext2_ino_t ino, int flags);
errcode_t ext2fs_unlink(ext2_filsys fs, ext2_ino_t dir, const char *name,
/* res_gdt.c */
extern errcode_t ext2fs_create_resize_inode(ext2_filsys fs);
+/* rw_bitmaps.c */
+extern errcode_t ext2fs_rw_bitmaps(ext2_filsys fs, int flags, int num_threads);
+extern errcode_t ext2fs_read_bitmaps(ext2_filsys fs);
+extern errcode_t ext2fs_read_inode_bitmap (ext2_filsys fs);
+extern errcode_t ext2fs_read_block_bitmap(ext2_filsys fs);
+extern errcode_t ext2fs_write_bitmaps(ext2_filsys fs);
+extern errcode_t ext2fs_write_inode_bitmap(ext2_filsys fs);
+extern errcode_t ext2fs_write_block_bitmap (ext2_filsys fs);
+
/*sha256.c */
#define EXT2FS_SHA256_LENGTH 32
#if 0
extern errcode_t ext2fs_free_mem(void *ptr);
extern errcode_t ext2fs_resize_mem(unsigned long old_size,
unsigned long size, void *ptr);
+extern errcode_t ext2fs_resize_array(unsigned long old_count, unsigned long count,
+ unsigned long size, void *ptr);
extern void ext2fs_mark_super_dirty(ext2_filsys fs);
extern void ext2fs_mark_changed(ext2_filsys fs);
extern int ext2fs_test_changed(ext2_filsys fs);
extern void ext2fs_dirent_set_file_type(struct ext2_dir_entry *entry, int type);
extern struct ext2_inode *ext2fs_inode(struct ext2_inode_large * large_inode);
extern const struct ext2_inode *ext2fs_const_inode(const struct ext2_inode_large * large_inode);
-
+extern int ext2fs_inodes_per_orphan_block(ext2_filsys fs);
+extern struct ext4_orphan_block_tail *ext2fs_orphan_block_tail(ext2_filsys fs,
+ char *buf);
#endif
/*
return 0;
}
-_INLINE_ errcode_t ext2fs_get_array(unsigned long count, unsigned long size, void *ptr)
+_INLINE_ errcode_t ext2fs_get_array(unsigned long count, unsigned long size,
+ void *ptr)
{
if (count && (~0UL)/count < size)
return EXT2_ET_NO_MEMORY;
_INLINE_ errcode_t ext2fs_get_arrayzero(unsigned long count,
unsigned long size, void *ptr)
{
- void *pp;
-
if (count && (~0UL)/count < size)
return EXT2_ET_NO_MEMORY;
- pp = calloc(count, size);
- if (!pp)
- return EXT2_ET_NO_MEMORY;
- memcpy(ptr, &pp, sizeof(pp));
- return 0;
+
+ return ext2fs_get_memzero((size_t)count * size, ptr);
}
/*
memcpy(ptr, &p, sizeof(p));
return 0;
}
+
+/*
+ * Resize array. The 'ptr' arg must point to a pointer.
+ */
+_INLINE_ errcode_t ext2fs_resize_array(unsigned long size,
+ unsigned long old_count,
+ unsigned long count, void *ptr)
+{
+ unsigned long old_size;
+ errcode_t retval;
+
+ if (count && (~0UL)/count < size)
+ return EXT2_ET_NO_MEMORY;
+
+ size *= count;
+ old_size = size * old_count;
+ retval = ext2fs_resize_mem(old_size, size, ptr);
+ if (retval)
+ return retval;
+
+ if (size > old_size) {
+ void *p;
+
+ memcpy(&p, ptr, sizeof(p));
+ memset((char *)p + old_size, 0, size - old_size);
+ memcpy(ptr, &p, sizeof(p));
+ }
+
+ return 0;
+}
#endif /* Custom memory routines */
/*
_INLINE_ int ext2fs_htree_intnode_maxrecs(ext2_filsys fs, int blocks)
{
- return blocks * ((fs->blocksize - 8) / sizeof(struct ext2_dx_entry));
+ int csum_size = 0;
+
+ if ((EXT2_SB(fs->super)->s_feature_ro_compat &
+ EXT4_FEATURE_RO_COMPAT_METADATA_CSUM) != 0)
+ csum_size = sizeof(struct ext2_dx_tail);
+ return blocks * ((fs->blocksize - (8 + csum_size)) /
+ sizeof(struct ext2_dx_entry));
+}
+
+_INLINE_ struct ext2_dx_root_info *get_ext2_dx_root_info(ext2_filsys fs,
+ char *buf)
+{
+ struct ext2_dir_entry *de = (struct ext2_dir_entry *)buf;
+
+ if (!(fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_DIRDATA))
+ return (struct ext2_dx_root_info *)(buf +
+ EXT2_DIR_NAME_LEN(1) +
+ EXT2_DIR_NAME_LEN(2));
+
+ /* get dotdot first */
+ de = (struct ext2_dir_entry *)((char *)de + de->rec_len);
+
+ /* dx root info is after dotdot entry */
+ de = (struct ext2_dir_entry *)((char *)de + EXT2_DIR_REC_LEN(de));
+
+ return (struct ext2_dx_root_info *)de;
}
/*
_INLINE_ int ext2fs_dirent_name_len(const struct ext2_dir_entry *entry)
{
- return entry->name_len & 0xff;
+ return entry->name_len & EXT2_NAME_LEN;
}
_INLINE_ void ext2fs_dirent_set_name_len(struct ext2_dir_entry *entry, int len)
return (const struct ext2_inode *) large_inode;
}
+_INLINE_ int ext2fs_inodes_per_orphan_block(ext2_filsys fs)
+{
+ return (fs->blocksize - sizeof(struct ext4_orphan_block_tail)) /
+ sizeof(__u32);
+}
+
+_INLINE_ struct ext4_orphan_block_tail *
+ext2fs_orphan_block_tail(ext2_filsys fs, char *buf)
+{
+ return (struct ext4_orphan_block_tail *)(buf + fs->blocksize -
+ sizeof(struct ext4_orphan_block_tail));
+}
+
#undef _INLINE_
#endif