summaryrefslogtreecommitdiffstats
path: root/lib/ext2fs/ext2fs.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ext2fs/ext2fs.h')
-rw-r--r--lib/ext2fs/ext2fs.h110
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