1 /* 2 * linux/fs/ext4/bitmap.c 3 * 4 * Copyright (C) 1992, 1993, 1994, 1995 5 * Remy Card (card@masi.ibp.fr) 6 * Laboratoire MASI - Institut Blaise Pascal 7 * Universite Pierre et Marie Curie (Paris VI) 8 */ 9 10 #include <linux/buffer_head.h> 11 #include "ext4.h" 12 13 unsigned int ext4_count_free(char *bitmap, unsigned int numchars) 14 { 15 return numchars * BITS_PER_BYTE - memweight(bitmap, numchars); 16 } 17 18 int ext4_inode_bitmap_csum_verify(struct super_block *sb, ext4_group_t group, 19 struct ext4_group_desc *gdp, 20 struct buffer_head *bh, int sz) 21 { 22 __u32 hi; 23 __u32 provided, calculated; 24 struct ext4_sb_info *sbi = EXT4_SB(sb); 25 26 if (!ext4_has_metadata_csum(sb)) 27 return 1; 28 29 provided = le16_to_cpu(gdp->bg_inode_bitmap_csum_lo); 30 calculated = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)bh->b_data, sz); 31 if (sbi->s_desc_size >= EXT4_BG_INODE_BITMAP_CSUM_HI_END) { 32 hi = le16_to_cpu(gdp->bg_inode_bitmap_csum_hi); 33 provided |= (hi << 16); 34 } else 35 calculated &= 0xFFFF; 36 37 return provided == calculated; 38 } 39 40 void ext4_inode_bitmap_csum_set(struct super_block *sb, ext4_group_t group, 41 struct ext4_group_desc *gdp, 42 struct buffer_head *bh, int sz) 43 { 44 __u32 csum; 45 struct ext4_sb_info *sbi = EXT4_SB(sb); 46 47 if (!ext4_has_metadata_csum(sb)) 48 return; 49 50 csum = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)bh->b_data, sz); 51 gdp->bg_inode_bitmap_csum_lo = cpu_to_le16(csum & 0xFFFF); 52 if (sbi->s_desc_size >= EXT4_BG_INODE_BITMAP_CSUM_HI_END) 53 gdp->bg_inode_bitmap_csum_hi = cpu_to_le16(csum >> 16); 54 } 55 56 int ext4_block_bitmap_csum_verify(struct super_block *sb, ext4_group_t group, 57 struct ext4_group_desc *gdp, 58 struct buffer_head *bh) 59 { 60 __u32 hi; 61 __u32 provided, calculated; 62 struct ext4_sb_info *sbi = EXT4_SB(sb); 63 int sz = EXT4_CLUSTERS_PER_GROUP(sb) / 8; 64 65 if (!ext4_has_metadata_csum(sb)) 66 return 1; 67 68 provided = le16_to_cpu(gdp->bg_block_bitmap_csum_lo); 69 calculated = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)bh->b_data, sz); 70 if (sbi->s_desc_size >= EXT4_BG_BLOCK_BITMAP_CSUM_HI_END) { 71 hi = le16_to_cpu(gdp->bg_block_bitmap_csum_hi); 72 provided |= (hi << 16); 73 } else 74 calculated &= 0xFFFF; 75 76 if (provided == calculated) 77 return 1; 78 79 return 0; 80 } 81 82 void ext4_block_bitmap_csum_set(struct super_block *sb, ext4_group_t group, 83 struct ext4_group_desc *gdp, 84 struct buffer_head *bh) 85 { 86 int sz = EXT4_CLUSTERS_PER_GROUP(sb) / 8; 87 __u32 csum; 88 struct ext4_sb_info *sbi = EXT4_SB(sb); 89 90 if (!ext4_has_metadata_csum(sb)) 91 return; 92 93 csum = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)bh->b_data, sz); 94 gdp->bg_block_bitmap_csum_lo = cpu_to_le16(csum & 0xFFFF); 95 if (sbi->s_desc_size >= EXT4_BG_BLOCK_BITMAP_CSUM_HI_END) 96 gdp->bg_block_bitmap_csum_hi = cpu_to_le16(csum >> 16); 97 } 98