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 <linux/jbd2.h> 12 #include "ext4.h" 13 14 unsigned int ext4_count_free(char *bitmap, unsigned int numchars) 15 { 16 return numchars * BITS_PER_BYTE - memweight(bitmap, numchars); 17 } 18 19 int ext4_inode_bitmap_csum_verify(struct super_block *sb, ext4_group_t group, 20 struct ext4_group_desc *gdp, 21 struct buffer_head *bh, int sz) 22 { 23 __u32 hi; 24 __u32 provided, calculated; 25 struct ext4_sb_info *sbi = EXT4_SB(sb); 26 27 if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, 28 EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) 29 return 1; 30 31 provided = le16_to_cpu(gdp->bg_inode_bitmap_csum_lo); 32 calculated = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)bh->b_data, sz); 33 if (sbi->s_desc_size >= EXT4_BG_INODE_BITMAP_CSUM_HI_END) { 34 hi = le16_to_cpu(gdp->bg_inode_bitmap_csum_hi); 35 provided |= (hi << 16); 36 } else 37 calculated &= 0xFFFF; 38 39 return provided == calculated; 40 } 41 42 void ext4_inode_bitmap_csum_set(struct super_block *sb, ext4_group_t group, 43 struct ext4_group_desc *gdp, 44 struct buffer_head *bh, int sz) 45 { 46 __u32 csum; 47 struct ext4_sb_info *sbi = EXT4_SB(sb); 48 49 if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, 50 EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) 51 return; 52 53 csum = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)bh->b_data, sz); 54 gdp->bg_inode_bitmap_csum_lo = cpu_to_le16(csum & 0xFFFF); 55 if (sbi->s_desc_size >= EXT4_BG_INODE_BITMAP_CSUM_HI_END) 56 gdp->bg_inode_bitmap_csum_hi = cpu_to_le16(csum >> 16); 57 } 58 59 int ext4_block_bitmap_csum_verify(struct super_block *sb, ext4_group_t group, 60 struct ext4_group_desc *gdp, 61 struct buffer_head *bh) 62 { 63 __u32 hi; 64 __u32 provided, calculated; 65 struct ext4_sb_info *sbi = EXT4_SB(sb); 66 int sz = EXT4_CLUSTERS_PER_GROUP(sb) / 8; 67 68 if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, 69 EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) 70 return 1; 71 72 provided = le16_to_cpu(gdp->bg_block_bitmap_csum_lo); 73 calculated = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)bh->b_data, sz); 74 if (sbi->s_desc_size >= EXT4_BG_BLOCK_BITMAP_CSUM_HI_END) { 75 hi = le16_to_cpu(gdp->bg_block_bitmap_csum_hi); 76 provided |= (hi << 16); 77 } else 78 calculated &= 0xFFFF; 79 80 if (provided == calculated) 81 return 1; 82 83 return 0; 84 } 85 86 void ext4_block_bitmap_csum_set(struct super_block *sb, ext4_group_t group, 87 struct ext4_group_desc *gdp, 88 struct buffer_head *bh) 89 { 90 int sz = EXT4_CLUSTERS_PER_GROUP(sb) / 8; 91 __u32 csum; 92 struct ext4_sb_info *sbi = EXT4_SB(sb); 93 94 if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, 95 EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) 96 return; 97 98 csum = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)bh->b_data, sz); 99 gdp->bg_block_bitmap_csum_lo = cpu_to_le16(csum & 0xFFFF); 100 if (sbi->s_desc_size >= EXT4_BG_BLOCK_BITMAP_CSUM_HI_END) 101 gdp->bg_block_bitmap_csum_hi = cpu_to_le16(csum >> 16); 102 } 103