diff options
Diffstat (limited to 'lib/ext2fs/ext2fs.h')
-rw-r--r-- | lib/ext2fs/ext2fs.h | 110 |
1 files changed, 109 insertions, 1 deletions
diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h index 72c60d2..6e87829 100644 --- a/lib/ext2fs/ext2fs.h +++ b/lib/ext2fs/ext2fs.h @@ -222,6 +222,11 @@ typedef struct ext2_file *ext2_file_t; #define EXT2_FLAG_IGNORE_SWAP_DIRENT 0x8000000 /* + * Internal flags for use by the ext2fs library only + */ +#define EXT2_FLAG2_USE_FAKE_TIME 0x000000001 + +/* * Special flag in the ext2 inode i_flag field that means that this is * a new inode. (So that ext2_write_inode() can clear extra fields.) */ @@ -275,10 +280,11 @@ struct struct_ext2_filsys { int cluster_ratio_bits; __u16 default_bitmap_type; __u16 pad; + __u32 flags2; /* * Reserved for future expansion */ - __u32 reserved[5]; + __u32 reserved[4]; /* * Reserved for the use of the calling application. @@ -579,6 +585,73 @@ typedef struct ext2_struct_inode_scan *ext2_inode_scan; */ #define EXT2_I_SIZE(i) ((i)->i_size | ((__u64) (i)->i_size_high << 32)) +static inline __u32 __encode_extra_time(time_t seconds, __u32 nsec) +{ + __u32 extra = 0; + +#if (SIZEOF_TIME_T > 4) + extra = ((seconds - (__s32)(seconds & 0xffffffff)) >> 32) & + EXT4_EPOCH_MASK; +#endif + return extra | (nsec << EXT4_EPOCH_BITS); +} +static inline time_t __decode_extra_sec(time_t seconds, __u32 extra) +{ +#if (SIZEOF_TIME_T > 4) + if (extra & EXT4_EPOCH_MASK) + seconds += ((time_t)(extra & EXT4_EPOCH_MASK) << 32); +#endif + return seconds; +} +static inline __u32 __decode_extra_nsec(__u32 extra) +{ + return (extra & EXT4_NSEC_MASK) >> EXT4_EPOCH_BITS; +} +#define ext2fs_inode_actual_size(inode) \ + ((size_t)(EXT2_GOOD_OLD_INODE_SIZE + \ + (sizeof(*inode) > EXT2_GOOD_OLD_INODE_SIZE ? \ + ((struct ext2_inode_large *)(inode))->i_extra_isize : 0))) +#define clamp(val, min, max) ((val) < (min) ? (min) : ((val) > (max) ? \ + (max) : (val))) +#define ext2fs_inode_xtime_set(inode, field, sec) \ +do { \ + if (ext2fs_inode_includes(ext2fs_inode_actual_size(inode), \ + field ## _extra)) { \ + (inode)->field = (__s32)(sec & 0xfffffff); \ + ((struct ext2_inode_large *)(inode))->field ## _extra = \ + __encode_extra_time(sec, 0); \ + } else { \ + (inode)->field = clamp(sec, INT32_MIN, INT32_MAX); \ + } \ +} while (0) +#define ext2fs_inode_xtime_get(inode, field) \ +(ext2fs_inode_includes(ext2fs_inode_actual_size(inode), field ## _extra) ? \ + __decode_extra_sec((inode)->field, \ + ((struct ext2_inode_large *)(inode))->field ## _extra) : \ + (time_t)(inode)->field) + +static inline void __sb_set_tstamp(__u32 *lo, __u8 *hi, time_t seconds) +{ + *lo = seconds & 0xffffffff; +#if (SIZEOF_TIME_T > 4) + *hi = (seconds >> 32) & EXT4_EPOCH_MASK; +#else + *hi = 0; +#endif +} +static inline time_t __sb_get_tstamp(__u32 *lo, __u8 *hi) +{ +#if (SIZEOF_TIME_T == 4) + return *lo; +#else + return ((time_t)(*hi) << 32) | *lo; +#endif +} +#define ext2fs_set_tstamp(sb, field, seconds) \ + __sb_set_tstamp(&(sb)->field, &(sb)->field ## _hi, seconds) +#define ext2fs_get_tstamp(sb, field) \ + __sb_get_tstamp(&(sb)->field, &(sb)->field ## _hi) + /* * ext2_icount_t abstraction */ @@ -795,6 +868,10 @@ errcode_t ext2fs_alloc_range(ext2_filsys fs, int flags, blk64_t goal, 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, @@ -1483,6 +1560,13 @@ 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); + +/* getenv.c */ +extern char *ext2fs_safe_getenv(const char *arg); /* get_num_dirs.c */ extern errcode_t ext2fs_get_num_dirs(ext2_filsys fs, ext2_ino_t *ret_num_dirs); @@ -2217,6 +2301,30 @@ static inline unsigned int ext2_dir_htree_level(ext2_filsys fs) return EXT4_HTREE_LEVEL_COMPAT; } +/* + * We explicitly decided not to reserve space for a 64-bit dtime, + * since it's never displayed or exposed to userspace. The dtime + * field is used a linked list for the ophan list, and for forensic + * purposes when trying to determine when an inode was deleted. So + * right after the 2038 epoch, a deleted inode might end up with a + * dtime which is zero or smaller than the number of inodes, which + * will result in e2fsck reporting a potential problems. So when we + * set the dtime, make sure that the dtime won't be mistaken for an + * inode number. + */ +static inline void ext2fs_set_dtime(ext2_filsys fs, struct ext2_inode *inode) +{ + __u32 t; + + if (fs->now || (fs->flags2 & EXT2_FLAG2_USE_FAKE_TIME)) + t = fs->now & 0xFFFFFFFF; + else + t = time(NULL) & 0xFFFFFFFF; + if (t < fs->super->s_inodes_count) + t = fs->super->s_inodes_count; + inode->i_dtime = t; +} + #ifdef __cplusplus } #endif |