|
@@ -288,7 +288,7 @@ struct ext4_inode {
|
|
__le16 i_uid; /* Low 16 bits of Owner Uid */
|
|
__le16 i_uid; /* Low 16 bits of Owner Uid */
|
|
__le32 i_size; /* Size in bytes */
|
|
__le32 i_size; /* Size in bytes */
|
|
__le32 i_atime; /* Access time */
|
|
__le32 i_atime; /* Access time */
|
|
- __le32 i_ctime; /* Creation time */
|
|
|
|
|
|
+ __le32 i_ctime; /* Inode Change time */
|
|
__le32 i_mtime; /* Modification time */
|
|
__le32 i_mtime; /* Modification time */
|
|
__le32 i_dtime; /* Deletion Time */
|
|
__le32 i_dtime; /* Deletion Time */
|
|
__le16 i_gid; /* Low 16 bits of Group Id */
|
|
__le16 i_gid; /* Low 16 bits of Group Id */
|
|
@@ -337,10 +337,85 @@ struct ext4_inode {
|
|
} osd2; /* OS dependent 2 */
|
|
} osd2; /* OS dependent 2 */
|
|
__le16 i_extra_isize;
|
|
__le16 i_extra_isize;
|
|
__le16 i_pad1;
|
|
__le16 i_pad1;
|
|
|
|
+ __le32 i_ctime_extra; /* extra Change time (nsec << 2 | epoch) */
|
|
|
|
+ __le32 i_mtime_extra; /* extra Modification time(nsec << 2 | epoch) */
|
|
|
|
+ __le32 i_atime_extra; /* extra Access time (nsec << 2 | epoch) */
|
|
|
|
+ __le32 i_crtime; /* File Creation time */
|
|
|
|
+ __le32 i_crtime_extra; /* extra FileCreationtime (nsec << 2 | epoch) */
|
|
};
|
|
};
|
|
|
|
|
|
#define i_size_high i_dir_acl
|
|
#define i_size_high i_dir_acl
|
|
|
|
|
|
|
|
+#define EXT4_EPOCH_BITS 2
|
|
|
|
+#define EXT4_EPOCH_MASK ((1 << EXT4_EPOCH_BITS) - 1)
|
|
|
|
+#define EXT4_NSEC_MASK (~0UL << EXT4_EPOCH_BITS)
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * Extended fields will fit into an inode if the filesystem was formatted
|
|
|
|
+ * with large inodes (-I 256 or larger) and there are not currently any EAs
|
|
|
|
+ * consuming all of the available space. For new inodes we always reserve
|
|
|
|
+ * enough space for the kernel's known extended fields, but for inodes
|
|
|
|
+ * created with an old kernel this might not have been the case. None of
|
|
|
|
+ * the extended inode fields is critical for correct filesystem operation.
|
|
|
|
+ * This macro checks if a certain field fits in the inode. Note that
|
|
|
|
+ * inode-size = GOOD_OLD_INODE_SIZE + i_extra_isize
|
|
|
|
+ */
|
|
|
|
+#define EXT4_FITS_IN_INODE(ext4_inode, einode, field) \
|
|
|
|
+ ((offsetof(typeof(*ext4_inode), field) + \
|
|
|
|
+ sizeof((ext4_inode)->field)) \
|
|
|
|
+ <= (EXT4_GOOD_OLD_INODE_SIZE + \
|
|
|
|
+ (einode)->i_extra_isize)) \
|
|
|
|
+
|
|
|
|
+static inline __le32 ext4_encode_extra_time(struct timespec *time)
|
|
|
|
+{
|
|
|
|
+ return cpu_to_le32((sizeof(time->tv_sec) > 4 ?
|
|
|
|
+ time->tv_sec >> 32 : 0) |
|
|
|
|
+ ((time->tv_nsec << 2) & EXT4_NSEC_MASK));
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static inline void ext4_decode_extra_time(struct timespec *time, __le32 extra)
|
|
|
|
+{
|
|
|
|
+ if (sizeof(time->tv_sec) > 4)
|
|
|
|
+ time->tv_sec |= (__u64)(le32_to_cpu(extra) & EXT4_EPOCH_MASK)
|
|
|
|
+ << 32;
|
|
|
|
+ time->tv_nsec = (le32_to_cpu(extra) & EXT4_NSEC_MASK) >> 2;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#define EXT4_INODE_SET_XTIME(xtime, inode, raw_inode) \
|
|
|
|
+do { \
|
|
|
|
+ (raw_inode)->xtime = cpu_to_le32((inode)->xtime.tv_sec); \
|
|
|
|
+ if (EXT4_FITS_IN_INODE(raw_inode, EXT4_I(inode), xtime ## _extra)) \
|
|
|
|
+ (raw_inode)->xtime ## _extra = \
|
|
|
|
+ ext4_encode_extra_time(&(inode)->xtime); \
|
|
|
|
+} while (0)
|
|
|
|
+
|
|
|
|
+#define EXT4_EINODE_SET_XTIME(xtime, einode, raw_inode) \
|
|
|
|
+do { \
|
|
|
|
+ if (EXT4_FITS_IN_INODE(raw_inode, einode, xtime)) \
|
|
|
|
+ (raw_inode)->xtime = cpu_to_le32((einode)->xtime.tv_sec); \
|
|
|
|
+ if (EXT4_FITS_IN_INODE(raw_inode, einode, xtime ## _extra)) \
|
|
|
|
+ (raw_inode)->xtime ## _extra = \
|
|
|
|
+ ext4_encode_extra_time(&(einode)->xtime); \
|
|
|
|
+} while (0)
|
|
|
|
+
|
|
|
|
+#define EXT4_INODE_GET_XTIME(xtime, inode, raw_inode) \
|
|
|
|
+do { \
|
|
|
|
+ (inode)->xtime.tv_sec = (signed)le32_to_cpu((raw_inode)->xtime); \
|
|
|
|
+ if (EXT4_FITS_IN_INODE(raw_inode, EXT4_I(inode), xtime ## _extra)) \
|
|
|
|
+ ext4_decode_extra_time(&(inode)->xtime, \
|
|
|
|
+ raw_inode->xtime ## _extra); \
|
|
|
|
+} while (0)
|
|
|
|
+
|
|
|
|
+#define EXT4_EINODE_GET_XTIME(xtime, einode, raw_inode) \
|
|
|
|
+do { \
|
|
|
|
+ if (EXT4_FITS_IN_INODE(raw_inode, einode, xtime)) \
|
|
|
|
+ (einode)->xtime.tv_sec = \
|
|
|
|
+ (signed)le32_to_cpu((raw_inode)->xtime); \
|
|
|
|
+ if (EXT4_FITS_IN_INODE(raw_inode, einode, xtime ## _extra)) \
|
|
|
|
+ ext4_decode_extra_time(&(einode)->xtime, \
|
|
|
|
+ raw_inode->xtime ## _extra); \
|
|
|
|
+} while (0)
|
|
|
|
+
|
|
#if defined(__KERNEL__) || defined(__linux__)
|
|
#if defined(__KERNEL__) || defined(__linux__)
|
|
#define i_reserved1 osd1.linux1.l_i_reserved1
|
|
#define i_reserved1 osd1.linux1.l_i_reserved1
|
|
#define i_frag osd2.linux2.l_i_frag
|
|
#define i_frag osd2.linux2.l_i_frag
|
|
@@ -539,6 +614,13 @@ static inline struct ext4_inode_info *EXT4_I(struct inode *inode)
|
|
return container_of(inode, struct ext4_inode_info, vfs_inode);
|
|
return container_of(inode, struct ext4_inode_info, vfs_inode);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static inline struct timespec ext4_current_time(struct inode *inode)
|
|
|
|
+{
|
|
|
|
+ return (inode->i_sb->s_time_gran < NSEC_PER_SEC) ?
|
|
|
|
+ current_fs_time(inode->i_sb) : CURRENT_TIME_SEC;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
static inline int ext4_valid_inum(struct super_block *sb, unsigned long ino)
|
|
static inline int ext4_valid_inum(struct super_block *sb, unsigned long ino)
|
|
{
|
|
{
|
|
return ino == EXT4_ROOT_INO ||
|
|
return ino == EXT4_ROOT_INO ||
|
|
@@ -609,6 +691,7 @@ static inline int ext4_valid_inum(struct super_block *sb, unsigned long ino)
|
|
#define EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001
|
|
#define EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001
|
|
#define EXT4_FEATURE_RO_COMPAT_LARGE_FILE 0x0002
|
|
#define EXT4_FEATURE_RO_COMPAT_LARGE_FILE 0x0002
|
|
#define EXT4_FEATURE_RO_COMPAT_BTREE_DIR 0x0004
|
|
#define EXT4_FEATURE_RO_COMPAT_BTREE_DIR 0x0004
|
|
|
|
+#define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE 0x0040
|
|
|
|
|
|
#define EXT4_FEATURE_INCOMPAT_COMPRESSION 0x0001
|
|
#define EXT4_FEATURE_INCOMPAT_COMPRESSION 0x0001
|
|
#define EXT4_FEATURE_INCOMPAT_FILETYPE 0x0002
|
|
#define EXT4_FEATURE_INCOMPAT_FILETYPE 0x0002
|
|
@@ -626,6 +709,7 @@ static inline int ext4_valid_inum(struct super_block *sb, unsigned long ino)
|
|
EXT4_FEATURE_INCOMPAT_64BIT)
|
|
EXT4_FEATURE_INCOMPAT_64BIT)
|
|
#define EXT4_FEATURE_RO_COMPAT_SUPP (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER| \
|
|
#define EXT4_FEATURE_RO_COMPAT_SUPP (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER| \
|
|
EXT4_FEATURE_RO_COMPAT_LARGE_FILE| \
|
|
EXT4_FEATURE_RO_COMPAT_LARGE_FILE| \
|
|
|
|
+ EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE | \
|
|
EXT4_FEATURE_RO_COMPAT_BTREE_DIR)
|
|
EXT4_FEATURE_RO_COMPAT_BTREE_DIR)
|
|
|
|
|
|
/*
|
|
/*
|