Skip to content

Commit

Permalink
ext4: change on-disk layout to support extended metadata checksumming
Browse files Browse the repository at this point in the history
Define flags and change structure definitions to allow checksumming of
ext4 metadata.

Signed-off-by: Darrick J. Wong <[email protected]>
Signed-off-by: "Theodore Ts'o" <[email protected]>
  • Loading branch information
Darrick J. Wong authored and tytso committed Apr 29, 2012
1 parent f848912 commit e615391
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 9 deletions.
47 changes: 39 additions & 8 deletions fs/ext4/ext4.h
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,9 @@ struct ext4_group_desc
__le16 bg_free_inodes_count_lo;/* Free inodes count */
__le16 bg_used_dirs_count_lo; /* Directories count */
__le16 bg_flags; /* EXT4_BG_flags (INODE_UNINIT, etc) */
__u32 bg_reserved[2]; /* Likely block/inode bitmap checksum */
__le32 bg_exclude_bitmap_lo; /* Exclude bitmap for snapshots */
__le16 bg_block_bitmap_csum_lo;/* crc32c(s_uuid+grp_num+bbitmap) LE */
__le16 bg_inode_bitmap_csum_lo;/* crc32c(s_uuid+grp_num+ibitmap) LE */
__le16 bg_itable_unused_lo; /* Unused inodes count */
__le16 bg_checksum; /* crc16(sb_uuid+group+desc) */
__le32 bg_block_bitmap_hi; /* Blocks bitmap block MSB */
Expand All @@ -308,7 +310,10 @@ struct ext4_group_desc
__le16 bg_free_inodes_count_hi;/* Free inodes count MSB */
__le16 bg_used_dirs_count_hi; /* Directories count MSB */
__le16 bg_itable_unused_hi; /* Unused inodes count MSB */
__u32 bg_reserved2[3];
__le32 bg_exclude_bitmap_hi; /* Exclude bitmap block MSB */
__le16 bg_block_bitmap_csum_hi;/* crc32c(s_uuid+grp_num+bbitmap) BE */
__le16 bg_inode_bitmap_csum_hi;/* crc32c(s_uuid+grp_num+ibitmap) BE */
__u32 bg_reserved;
};

/*
Expand Down Expand Up @@ -650,7 +655,8 @@ struct ext4_inode {
__le16 l_i_file_acl_high;
__le16 l_i_uid_high; /* these 2 fields */
__le16 l_i_gid_high; /* were reserved2[0] */
__u32 l_i_reserved2;
__le16 l_i_checksum_lo;/* crc32c(uuid+inum+inode) LE */
__le16 l_i_reserved;
} linux2;
struct {
__le16 h_i_reserved1; /* Obsoleted fragment number/size which are removed in ext4 */
Expand All @@ -666,7 +672,7 @@ struct ext4_inode {
} masix2;
} osd2; /* OS dependent 2 */
__le16 i_extra_isize;
__le16 i_pad1;
__le16 i_checksum_hi; /* crc32c(uuid+inum+inode) BE */
__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) */
Expand Down Expand Up @@ -768,7 +774,7 @@ do { \
#define i_gid_low i_gid
#define i_uid_high osd2.linux2.l_i_uid_high
#define i_gid_high osd2.linux2.l_i_gid_high
#define i_reserved2 osd2.linux2.l_i_reserved2
#define i_checksum_lo osd2.linux2.l_i_checksum_lo

#elif defined(__GNU__)

Expand Down Expand Up @@ -1001,6 +1007,9 @@ extern void ext4_set_bits(void *bm, int cur, int len);
#define EXT4_ERRORS_PANIC 3 /* Panic */
#define EXT4_ERRORS_DEFAULT EXT4_ERRORS_CONTINUE

/* Metadata checksum algorithm codes */
#define EXT4_CRC32C_CHKSUM 1

/*
* Structure of the super block
*/
Expand Down Expand Up @@ -1087,7 +1096,7 @@ struct ext4_super_block {
__le64 s_mmp_block; /* Block for multi-mount protection */
__le32 s_raid_stripe_width; /* blocks on all data disks (N*stride)*/
__u8 s_log_groups_per_flex; /* FLEX_BG group size */
__u8 s_reserved_char_pad;
__u8 s_checksum_type; /* metadata checksum algorithm used */
__le16 s_reserved_pad;
__le64 s_kbytes_written; /* nr of lifetime kilobytes written */
__le32 s_snapshot_inum; /* Inode number of active snapshot */
Expand All @@ -1113,7 +1122,8 @@ struct ext4_super_block {
__le32 s_usr_quota_inum; /* inode for tracking user quota */
__le32 s_grp_quota_inum; /* inode for tracking group quota */
__le32 s_overhead_clusters; /* overhead blocks/clusters in fs */
__le32 s_reserved[109]; /* Padding to the end of the block */
__le32 s_reserved[108]; /* Padding to the end of the block */
__le32 s_checksum; /* crc32c(superblock) */
};

#define EXT4_S_ERR_LEN (EXT4_S_ERR_END - EXT4_S_ERR_START)
Expand Down Expand Up @@ -1414,6 +1424,12 @@ static inline void ext4_clear_state_flags(struct ext4_inode_info *ei)
#define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE 0x0040
#define EXT4_FEATURE_RO_COMPAT_QUOTA 0x0100
#define EXT4_FEATURE_RO_COMPAT_BIGALLOC 0x0200
/*
* METADATA_CSUM also enables group descriptor checksums (GDT_CSUM). When
* METADATA_CSUM is set, group descriptor checksums use the same algorithm as
* all other data structures' checksums. However, the METADATA_CSUM and
* GDT_CSUM bits are mutually exclusive.
*/
#define EXT4_FEATURE_RO_COMPAT_METADATA_CSUM 0x0400

#define EXT4_FEATURE_INCOMPAT_COMPRESSION 0x0001
Expand Down Expand Up @@ -1526,6 +1542,18 @@ struct ext4_dir_entry_2 {
char name[EXT4_NAME_LEN]; /* File name */
};

/*
* This is a bogus directory entry at the end of each leaf block that
* records checksums.
*/
struct ext4_dir_entry_tail {
__le32 det_reserved_zero1; /* Pretend to be unused */
__le16 det_rec_len; /* 12 */
__u8 det_reserved_zero2; /* Zero name length */
__u8 det_reserved_ft; /* 0xDE, fake file type */
__le32 det_checksum; /* crc32c(uuid+inum+dirblock) */
};

/*
* Ext4 directory file types. Only the low 3 bits are used. The
* other bits are reserved for now.
Expand All @@ -1541,6 +1569,8 @@ struct ext4_dir_entry_2 {

#define EXT4_FT_MAX 8

#define EXT4_FT_DIR_CSUM 0xDE

/*
* EXT4_DIR_PAD defines the directory entries boundaries
*
Expand Down Expand Up @@ -1741,7 +1771,8 @@ struct mmp_struct {
__le16 mmp_check_interval;

__le16 mmp_pad1;
__le32 mmp_pad2[227];
__le32 mmp_pad2[226];
__le32 mmp_checksum; /* crc32c(uuid+mmp_block) */
};

/* arguments passed to the mmp thread */
Expand Down
13 changes: 13 additions & 0 deletions fs/ext4/ext4_extents.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,21 @@
* ext4_inode has i_block array (60 bytes total).
* The first 12 bytes store ext4_extent_header;
* the remainder stores an array of ext4_extent.
* For non-inode extent blocks, ext4_extent_tail
* follows the array.
*/

/*
* This is the extent tail on-disk structure.
* All other extent structures are 12 bytes long. It turns out that
* block_size % 12 >= 4 for at least all powers of 2 greater than 512, which
* covers all valid ext4 block sizes. Therefore, this tail structure can be
* crammed into the end of the block without having to rebalance the tree.
*/
struct ext4_extent_tail {
__le32 et_checksum; /* crc32c(uuid+inum+extent_block) */
};

/*
* This is the extent on-disk structure.
* It's used at the bottom of the tree.
Expand Down
8 changes: 8 additions & 0 deletions fs/ext4/namei.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,14 @@ struct dx_map_entry
u16 size;
};

/*
* This goes at the end of each htree block.
*/
struct dx_tail {
u32 dt_reserved;
__le32 dt_checksum; /* crc32c(uuid+inum+dirblock) */
};

static inline ext4_lblk_t dx_get_block(struct dx_entry *entry);
static void dx_set_block(struct dx_entry *entry, ext4_lblk_t value);
static inline unsigned dx_get_hash(struct dx_entry *entry);
Expand Down
4 changes: 3 additions & 1 deletion fs/ext4/xattr.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ struct ext4_xattr_header {
__le32 h_refcount; /* reference count */
__le32 h_blocks; /* number of disk blocks used */
__le32 h_hash; /* hash value of all attributes */
__u32 h_reserved[4]; /* zero right now */
__le32 h_checksum; /* crc32c(uuid+id+xattrblock) */
/* id = inum if refcount=1, blknum otherwise */
__u32 h_reserved[3]; /* zero right now */
};

struct ext4_xattr_ibody_header {
Expand Down

0 comments on commit e615391

Please sign in to comment.