aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ext4/ext4.h47
-rw-r--r--fs/ext4/ext4_extents.h13
-rw-r--r--fs/ext4/namei.c8
-rw-r--r--fs/ext4/xattr.h4
4 files changed, 63 insertions, 9 deletions
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 0e01e90add8..61dd739b64f 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -298,7 +298,9 @@ struct ext4_group_desc
298 __le16 bg_free_inodes_count_lo;/* Free inodes count */ 298 __le16 bg_free_inodes_count_lo;/* Free inodes count */
299 __le16 bg_used_dirs_count_lo; /* Directories count */ 299 __le16 bg_used_dirs_count_lo; /* Directories count */
300 __le16 bg_flags; /* EXT4_BG_flags (INODE_UNINIT, etc) */ 300 __le16 bg_flags; /* EXT4_BG_flags (INODE_UNINIT, etc) */
301 __u32 bg_reserved[2]; /* Likely block/inode bitmap checksum */ 301 __le32 bg_exclude_bitmap_lo; /* Exclude bitmap for snapshots */
302 __le16 bg_block_bitmap_csum_lo;/* crc32c(s_uuid+grp_num+bbitmap) LE */
303 __le16 bg_inode_bitmap_csum_lo;/* crc32c(s_uuid+grp_num+ibitmap) LE */
302 __le16 bg_itable_unused_lo; /* Unused inodes count */ 304 __le16 bg_itable_unused_lo; /* Unused inodes count */
303 __le16 bg_checksum; /* crc16(sb_uuid+group+desc) */ 305 __le16 bg_checksum; /* crc16(sb_uuid+group+desc) */
304 __le32 bg_block_bitmap_hi; /* Blocks bitmap block MSB */ 306 __le32 bg_block_bitmap_hi; /* Blocks bitmap block MSB */
@@ -308,7 +310,10 @@ struct ext4_group_desc
308 __le16 bg_free_inodes_count_hi;/* Free inodes count MSB */ 310 __le16 bg_free_inodes_count_hi;/* Free inodes count MSB */
309 __le16 bg_used_dirs_count_hi; /* Directories count MSB */ 311 __le16 bg_used_dirs_count_hi; /* Directories count MSB */
310 __le16 bg_itable_unused_hi; /* Unused inodes count MSB */ 312 __le16 bg_itable_unused_hi; /* Unused inodes count MSB */
311 __u32 bg_reserved2[3]; 313 __le32 bg_exclude_bitmap_hi; /* Exclude bitmap block MSB */
314 __le16 bg_block_bitmap_csum_hi;/* crc32c(s_uuid+grp_num+bbitmap) BE */
315 __le16 bg_inode_bitmap_csum_hi;/* crc32c(s_uuid+grp_num+ibitmap) BE */
316 __u32 bg_reserved;
312}; 317};
313 318
314/* 319/*
@@ -650,7 +655,8 @@ struct ext4_inode {
650 __le16 l_i_file_acl_high; 655 __le16 l_i_file_acl_high;
651 __le16 l_i_uid_high; /* these 2 fields */ 656 __le16 l_i_uid_high; /* these 2 fields */
652 __le16 l_i_gid_high; /* were reserved2[0] */ 657 __le16 l_i_gid_high; /* were reserved2[0] */
653 __u32 l_i_reserved2; 658 __le16 l_i_checksum_lo;/* crc32c(uuid+inum+inode) LE */
659 __le16 l_i_reserved;
654 } linux2; 660 } linux2;
655 struct { 661 struct {
656 __le16 h_i_reserved1; /* Obsoleted fragment number/size which are removed in ext4 */ 662 __le16 h_i_reserved1; /* Obsoleted fragment number/size which are removed in ext4 */
@@ -666,7 +672,7 @@ struct ext4_inode {
666 } masix2; 672 } masix2;
667 } osd2; /* OS dependent 2 */ 673 } osd2; /* OS dependent 2 */
668 __le16 i_extra_isize; 674 __le16 i_extra_isize;
669 __le16 i_pad1; 675 __le16 i_checksum_hi; /* crc32c(uuid+inum+inode) BE */
670 __le32 i_ctime_extra; /* extra Change time (nsec << 2 | epoch) */ 676 __le32 i_ctime_extra; /* extra Change time (nsec << 2 | epoch) */
671 __le32 i_mtime_extra; /* extra Modification time(nsec << 2 | epoch) */ 677 __le32 i_mtime_extra; /* extra Modification time(nsec << 2 | epoch) */
672 __le32 i_atime_extra; /* extra Access time (nsec << 2 | epoch) */ 678 __le32 i_atime_extra; /* extra Access time (nsec << 2 | epoch) */
@@ -768,7 +774,7 @@ do { \
768#define i_gid_low i_gid 774#define i_gid_low i_gid
769#define i_uid_high osd2.linux2.l_i_uid_high 775#define i_uid_high osd2.linux2.l_i_uid_high
770#define i_gid_high osd2.linux2.l_i_gid_high 776#define i_gid_high osd2.linux2.l_i_gid_high
771#define i_reserved2 osd2.linux2.l_i_reserved2 777#define i_checksum_lo osd2.linux2.l_i_checksum_lo
772 778
773#elif defined(__GNU__) 779#elif defined(__GNU__)
774 780
@@ -1001,6 +1007,9 @@ extern void ext4_set_bits(void *bm, int cur, int len);
1001#define EXT4_ERRORS_PANIC 3 /* Panic */ 1007#define EXT4_ERRORS_PANIC 3 /* Panic */
1002#define EXT4_ERRORS_DEFAULT EXT4_ERRORS_CONTINUE 1008#define EXT4_ERRORS_DEFAULT EXT4_ERRORS_CONTINUE
1003 1009
1010/* Metadata checksum algorithm codes */
1011#define EXT4_CRC32C_CHKSUM 1
1012
1004/* 1013/*
1005 * Structure of the super block 1014 * Structure of the super block
1006 */ 1015 */
@@ -1087,7 +1096,7 @@ struct ext4_super_block {
1087 __le64 s_mmp_block; /* Block for multi-mount protection */ 1096 __le64 s_mmp_block; /* Block for multi-mount protection */
1088 __le32 s_raid_stripe_width; /* blocks on all data disks (N*stride)*/ 1097 __le32 s_raid_stripe_width; /* blocks on all data disks (N*stride)*/
1089 __u8 s_log_groups_per_flex; /* FLEX_BG group size */ 1098 __u8 s_log_groups_per_flex; /* FLEX_BG group size */
1090 __u8 s_reserved_char_pad; 1099 __u8 s_checksum_type; /* metadata checksum algorithm used */
1091 __le16 s_reserved_pad; 1100 __le16 s_reserved_pad;
1092 __le64 s_kbytes_written; /* nr of lifetime kilobytes written */ 1101 __le64 s_kbytes_written; /* nr of lifetime kilobytes written */
1093 __le32 s_snapshot_inum; /* Inode number of active snapshot */ 1102 __le32 s_snapshot_inum; /* Inode number of active snapshot */
@@ -1113,7 +1122,8 @@ struct ext4_super_block {
1113 __le32 s_usr_quota_inum; /* inode for tracking user quota */ 1122 __le32 s_usr_quota_inum; /* inode for tracking user quota */
1114 __le32 s_grp_quota_inum; /* inode for tracking group quota */ 1123 __le32 s_grp_quota_inum; /* inode for tracking group quota */
1115 __le32 s_overhead_clusters; /* overhead blocks/clusters in fs */ 1124 __le32 s_overhead_clusters; /* overhead blocks/clusters in fs */
1116 __le32 s_reserved[109]; /* Padding to the end of the block */ 1125 __le32 s_reserved[108]; /* Padding to the end of the block */
1126 __le32 s_checksum; /* crc32c(superblock) */
1117}; 1127};
1118 1128
1119#define EXT4_S_ERR_LEN (EXT4_S_ERR_END - EXT4_S_ERR_START) 1129#define EXT4_S_ERR_LEN (EXT4_S_ERR_END - EXT4_S_ERR_START)
@@ -1414,6 +1424,12 @@ static inline void ext4_clear_state_flags(struct ext4_inode_info *ei)
1414#define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE 0x0040 1424#define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE 0x0040
1415#define EXT4_FEATURE_RO_COMPAT_QUOTA 0x0100 1425#define EXT4_FEATURE_RO_COMPAT_QUOTA 0x0100
1416#define EXT4_FEATURE_RO_COMPAT_BIGALLOC 0x0200 1426#define EXT4_FEATURE_RO_COMPAT_BIGALLOC 0x0200
1427/*
1428 * METADATA_CSUM also enables group descriptor checksums (GDT_CSUM). When
1429 * METADATA_CSUM is set, group descriptor checksums use the same algorithm as
1430 * all other data structures' checksums. However, the METADATA_CSUM and
1431 * GDT_CSUM bits are mutually exclusive.
1432 */
1417#define EXT4_FEATURE_RO_COMPAT_METADATA_CSUM 0x0400 1433#define EXT4_FEATURE_RO_COMPAT_METADATA_CSUM 0x0400
1418 1434
1419#define EXT4_FEATURE_INCOMPAT_COMPRESSION 0x0001 1435#define EXT4_FEATURE_INCOMPAT_COMPRESSION 0x0001
@@ -1527,6 +1543,18 @@ struct ext4_dir_entry_2 {
1527}; 1543};
1528 1544
1529/* 1545/*
1546 * This is a bogus directory entry at the end of each leaf block that
1547 * records checksums.
1548 */
1549struct ext4_dir_entry_tail {
1550 __le32 det_reserved_zero1; /* Pretend to be unused */
1551 __le16 det_rec_len; /* 12 */
1552 __u8 det_reserved_zero2; /* Zero name length */
1553 __u8 det_reserved_ft; /* 0xDE, fake file type */
1554 __le32 det_checksum; /* crc32c(uuid+inum+dirblock) */
1555};
1556
1557/*
1530 * Ext4 directory file types. Only the low 3 bits are used. The 1558 * Ext4 directory file types. Only the low 3 bits are used. The
1531 * other bits are reserved for now. 1559 * other bits are reserved for now.
1532 */ 1560 */
@@ -1541,6 +1569,8 @@ struct ext4_dir_entry_2 {
1541 1569
1542#define EXT4_FT_MAX 8 1570#define EXT4_FT_MAX 8
1543 1571
1572#define EXT4_FT_DIR_CSUM 0xDE
1573
1544/* 1574/*
1545 * EXT4_DIR_PAD defines the directory entries boundaries 1575 * EXT4_DIR_PAD defines the directory entries boundaries
1546 * 1576 *
@@ -1741,7 +1771,8 @@ struct mmp_struct {
1741 __le16 mmp_check_interval; 1771 __le16 mmp_check_interval;
1742 1772
1743 __le16 mmp_pad1; 1773 __le16 mmp_pad1;
1744 __le32 mmp_pad2[227]; 1774 __le32 mmp_pad2[226];
1775 __le32 mmp_checksum; /* crc32c(uuid+mmp_block) */
1745}; 1776};
1746 1777
1747/* arguments passed to the mmp thread */ 1778/* arguments passed to the mmp thread */
diff --git a/fs/ext4/ext4_extents.h b/fs/ext4/ext4_extents.h
index 0f58b86e3a0..94822e74ef7 100644
--- a/fs/ext4/ext4_extents.h
+++ b/fs/ext4/ext4_extents.h
@@ -63,9 +63,22 @@
63 * ext4_inode has i_block array (60 bytes total). 63 * ext4_inode has i_block array (60 bytes total).
64 * The first 12 bytes store ext4_extent_header; 64 * The first 12 bytes store ext4_extent_header;
65 * the remainder stores an array of ext4_extent. 65 * the remainder stores an array of ext4_extent.
66 * For non-inode extent blocks, ext4_extent_tail
67 * follows the array.
66 */ 68 */
67 69
68/* 70/*
71 * This is the extent tail on-disk structure.
72 * All other extent structures are 12 bytes long. It turns out that
73 * block_size % 12 >= 4 for at least all powers of 2 greater than 512, which
74 * covers all valid ext4 block sizes. Therefore, this tail structure can be
75 * crammed into the end of the block without having to rebalance the tree.
76 */
77struct ext4_extent_tail {
78 __le32 et_checksum; /* crc32c(uuid+inum+extent_block) */
79};
80
81/*
69 * This is the extent on-disk structure. 82 * This is the extent on-disk structure.
70 * It's used at the bottom of the tree. 83 * It's used at the bottom of the tree.
71 */ 84 */
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 349d7b3671c..b58bd5c8ffe 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -145,6 +145,14 @@ struct dx_map_entry
145 u16 size; 145 u16 size;
146}; 146};
147 147
148/*
149 * This goes at the end of each htree block.
150 */
151struct dx_tail {
152 u32 dt_reserved;
153 __le32 dt_checksum; /* crc32c(uuid+inum+dirblock) */
154};
155
148static inline ext4_lblk_t dx_get_block(struct dx_entry *entry); 156static inline ext4_lblk_t dx_get_block(struct dx_entry *entry);
149static void dx_set_block(struct dx_entry *entry, ext4_lblk_t value); 157static void dx_set_block(struct dx_entry *entry, ext4_lblk_t value);
150static inline unsigned dx_get_hash(struct dx_entry *entry); 158static inline unsigned dx_get_hash(struct dx_entry *entry);
diff --git a/fs/ext4/xattr.h b/fs/ext4/xattr.h
index 25b7387ff18..91f31ca7d9a 100644
--- a/fs/ext4/xattr.h
+++ b/fs/ext4/xattr.h
@@ -27,7 +27,9 @@ struct ext4_xattr_header {
27 __le32 h_refcount; /* reference count */ 27 __le32 h_refcount; /* reference count */
28 __le32 h_blocks; /* number of disk blocks used */ 28 __le32 h_blocks; /* number of disk blocks used */
29 __le32 h_hash; /* hash value of all attributes */ 29 __le32 h_hash; /* hash value of all attributes */
30 __u32 h_reserved[4]; /* zero right now */ 30 __le32 h_checksum; /* crc32c(uuid+id+xattrblock) */
31 /* id = inum if refcount=1, blknum otherwise */
32 __u32 h_reserved[3]; /* zero right now */
31}; 33};
32 34
33struct ext4_xattr_ibody_header { 35struct ext4_xattr_ibody_header {