1ac27a0ecSDave Kleikamp /* 2617ba13bSMingming Cao * linux/fs/ext4/bitmap.c 3ac27a0ecSDave Kleikamp * 4ac27a0ecSDave Kleikamp * Copyright (C) 1992, 1993, 1994, 1995 5ac27a0ecSDave Kleikamp * Remy Card (card@masi.ibp.fr) 6ac27a0ecSDave Kleikamp * Laboratoire MASI - Institut Blaise Pascal 7ac27a0ecSDave Kleikamp * Universite Pierre et Marie Curie (Paris VI) 8ac27a0ecSDave Kleikamp */ 9ac27a0ecSDave Kleikamp 10ac27a0ecSDave Kleikamp #include <linux/buffer_head.h> 11dab291afSMingming Cao #include <linux/jbd2.h> 123dcf5451SChristoph Hellwig #include "ext4.h" 13ac27a0ecSDave Kleikamp 14617ba13bSMingming Cao #ifdef EXT4FS_DEBUG 15ac27a0ecSDave Kleikamp 16febfcf91SPhilippe De Muyter static const int nibblemap[] = {4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0}; 17ac27a0ecSDave Kleikamp 18f6fb99caSTheodore Ts'o unsigned int ext4_count_free(char *bitmap, unsigned int numchars) 19ac27a0ecSDave Kleikamp { 20498e5f24STheodore Ts'o unsigned int i, sum = 0; 21ac27a0ecSDave Kleikamp 22ac27a0ecSDave Kleikamp for (i = 0; i < numchars; i++) 23f6fb99caSTheodore Ts'o sum += nibblemap[bitmap[i] & 0xf] + 24f6fb99caSTheodore Ts'o nibblemap[(bitmap[i] >> 4) & 0xf]; 25af5bc92dSTheodore Ts'o return sum; 26ac27a0ecSDave Kleikamp } 27ac27a0ecSDave Kleikamp 28617ba13bSMingming Cao #endif /* EXT4FS_DEBUG */ 29ac27a0ecSDave Kleikamp 3041a246d1SDarrick J. Wong int ext4_inode_bitmap_csum_verify(struct super_block *sb, ext4_group_t group, 3141a246d1SDarrick J. Wong struct ext4_group_desc *gdp, 3241a246d1SDarrick J. Wong struct buffer_head *bh, int sz) 3341a246d1SDarrick J. Wong { 3441a246d1SDarrick J. Wong __u32 hi; 3541a246d1SDarrick J. Wong __u32 provided, calculated; 3641a246d1SDarrick J. Wong struct ext4_sb_info *sbi = EXT4_SB(sb); 3741a246d1SDarrick J. Wong 3841a246d1SDarrick J. Wong if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, 3941a246d1SDarrick J. Wong EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) 4041a246d1SDarrick J. Wong return 1; 4141a246d1SDarrick J. Wong 4241a246d1SDarrick J. Wong provided = le16_to_cpu(gdp->bg_inode_bitmap_csum_lo); 4341a246d1SDarrick J. Wong calculated = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)bh->b_data, sz); 4441a246d1SDarrick J. Wong if (sbi->s_desc_size >= EXT4_BG_INODE_BITMAP_CSUM_HI_END) { 4541a246d1SDarrick J. Wong hi = le16_to_cpu(gdp->bg_inode_bitmap_csum_hi); 4641a246d1SDarrick J. Wong provided |= (hi << 16); 4741a246d1SDarrick J. Wong } else 4841a246d1SDarrick J. Wong calculated &= 0xFFFF; 4941a246d1SDarrick J. Wong 5041a246d1SDarrick J. Wong return provided == calculated; 5141a246d1SDarrick J. Wong } 5241a246d1SDarrick J. Wong 5341a246d1SDarrick J. Wong void ext4_inode_bitmap_csum_set(struct super_block *sb, ext4_group_t group, 5441a246d1SDarrick J. Wong struct ext4_group_desc *gdp, 5541a246d1SDarrick J. Wong struct buffer_head *bh, int sz) 5641a246d1SDarrick J. Wong { 5741a246d1SDarrick J. Wong __u32 csum; 5841a246d1SDarrick J. Wong struct ext4_sb_info *sbi = EXT4_SB(sb); 5941a246d1SDarrick J. Wong 6041a246d1SDarrick J. Wong if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, 6141a246d1SDarrick J. Wong EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) 6241a246d1SDarrick J. Wong return; 6341a246d1SDarrick J. Wong 6441a246d1SDarrick J. Wong csum = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)bh->b_data, sz); 6541a246d1SDarrick J. Wong gdp->bg_inode_bitmap_csum_lo = cpu_to_le16(csum & 0xFFFF); 6641a246d1SDarrick J. Wong if (sbi->s_desc_size >= EXT4_BG_INODE_BITMAP_CSUM_HI_END) 6741a246d1SDarrick J. Wong gdp->bg_inode_bitmap_csum_hi = cpu_to_le16(csum >> 16); 6841a246d1SDarrick J. Wong } 69fa77dcfaSDarrick J. Wong 70fa77dcfaSDarrick J. Wong int ext4_block_bitmap_csum_verify(struct super_block *sb, ext4_group_t group, 71fa77dcfaSDarrick J. Wong struct ext4_group_desc *gdp, 72fa77dcfaSDarrick J. Wong struct buffer_head *bh, int sz) 73fa77dcfaSDarrick J. Wong { 74fa77dcfaSDarrick J. Wong __u32 hi; 75fa77dcfaSDarrick J. Wong __u32 provided, calculated; 76fa77dcfaSDarrick J. Wong struct ext4_sb_info *sbi = EXT4_SB(sb); 77fa77dcfaSDarrick J. Wong 78fa77dcfaSDarrick J. Wong if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, 79fa77dcfaSDarrick J. Wong EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) 80fa77dcfaSDarrick J. Wong return 1; 81fa77dcfaSDarrick J. Wong 82fa77dcfaSDarrick J. Wong provided = le16_to_cpu(gdp->bg_block_bitmap_csum_lo); 83fa77dcfaSDarrick J. Wong calculated = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)bh->b_data, sz); 84fa77dcfaSDarrick J. Wong if (sbi->s_desc_size >= EXT4_BG_BLOCK_BITMAP_CSUM_HI_END) { 85fa77dcfaSDarrick J. Wong hi = le16_to_cpu(gdp->bg_block_bitmap_csum_hi); 86fa77dcfaSDarrick J. Wong provided |= (hi << 16); 87fa77dcfaSDarrick J. Wong } else 88fa77dcfaSDarrick J. Wong calculated &= 0xFFFF; 89fa77dcfaSDarrick J. Wong 90fa77dcfaSDarrick J. Wong if (provided == calculated) 91fa77dcfaSDarrick J. Wong return 1; 92fa77dcfaSDarrick J. Wong 93fa77dcfaSDarrick J. Wong ext4_error(sb, "Bad block bitmap checksum: block_group = %u", group); 94fa77dcfaSDarrick J. Wong return 0; 95fa77dcfaSDarrick J. Wong } 96fa77dcfaSDarrick J. Wong 97fa77dcfaSDarrick J. Wong void ext4_block_bitmap_csum_set(struct super_block *sb, ext4_group_t group, 98fa77dcfaSDarrick J. Wong struct ext4_group_desc *gdp, 99fa77dcfaSDarrick J. Wong struct buffer_head *bh, int sz) 100fa77dcfaSDarrick J. Wong { 101fa77dcfaSDarrick J. Wong __u32 csum; 102fa77dcfaSDarrick J. Wong struct ext4_sb_info *sbi = EXT4_SB(sb); 103fa77dcfaSDarrick J. Wong 104fa77dcfaSDarrick J. Wong if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, 105fa77dcfaSDarrick J. Wong EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) 106fa77dcfaSDarrick J. Wong return; 107fa77dcfaSDarrick J. Wong 108fa77dcfaSDarrick J. Wong csum = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)bh->b_data, sz); 109fa77dcfaSDarrick J. Wong gdp->bg_block_bitmap_csum_lo = cpu_to_le16(csum & 0xFFFF); 110fa77dcfaSDarrick J. Wong if (sbi->s_desc_size >= EXT4_BG_BLOCK_BITMAP_CSUM_HI_END) 111fa77dcfaSDarrick J. Wong gdp->bg_block_bitmap_csum_hi = cpu_to_le16(csum >> 16); 112fa77dcfaSDarrick J. Wong } 113