0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/buffer_head.h>
0012 #include "ext4.h"
0013
0014 unsigned int ext4_count_free(char *bitmap, unsigned int numchars)
0015 {
0016 return numchars * BITS_PER_BYTE - memweight(bitmap, numchars);
0017 }
0018
0019 int ext4_inode_bitmap_csum_verify(struct super_block *sb, ext4_group_t group,
0020 struct ext4_group_desc *gdp,
0021 struct buffer_head *bh, int sz)
0022 {
0023 __u32 hi;
0024 __u32 provided, calculated;
0025 struct ext4_sb_info *sbi = EXT4_SB(sb);
0026
0027 if (!ext4_has_metadata_csum(sb))
0028 return 1;
0029
0030 provided = le16_to_cpu(gdp->bg_inode_bitmap_csum_lo);
0031 calculated = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)bh->b_data, sz);
0032 if (sbi->s_desc_size >= EXT4_BG_INODE_BITMAP_CSUM_HI_END) {
0033 hi = le16_to_cpu(gdp->bg_inode_bitmap_csum_hi);
0034 provided |= (hi << 16);
0035 } else
0036 calculated &= 0xFFFF;
0037
0038 return provided == calculated;
0039 }
0040
0041 void ext4_inode_bitmap_csum_set(struct super_block *sb, ext4_group_t group,
0042 struct ext4_group_desc *gdp,
0043 struct buffer_head *bh, int sz)
0044 {
0045 __u32 csum;
0046 struct ext4_sb_info *sbi = EXT4_SB(sb);
0047
0048 if (!ext4_has_metadata_csum(sb))
0049 return;
0050
0051 csum = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)bh->b_data, sz);
0052 gdp->bg_inode_bitmap_csum_lo = cpu_to_le16(csum & 0xFFFF);
0053 if (sbi->s_desc_size >= EXT4_BG_INODE_BITMAP_CSUM_HI_END)
0054 gdp->bg_inode_bitmap_csum_hi = cpu_to_le16(csum >> 16);
0055 }
0056
0057 int ext4_block_bitmap_csum_verify(struct super_block *sb, ext4_group_t group,
0058 struct ext4_group_desc *gdp,
0059 struct buffer_head *bh)
0060 {
0061 __u32 hi;
0062 __u32 provided, calculated;
0063 struct ext4_sb_info *sbi = EXT4_SB(sb);
0064 int sz = EXT4_CLUSTERS_PER_GROUP(sb) / 8;
0065
0066 if (!ext4_has_metadata_csum(sb))
0067 return 1;
0068
0069 provided = le16_to_cpu(gdp->bg_block_bitmap_csum_lo);
0070 calculated = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)bh->b_data, sz);
0071 if (sbi->s_desc_size >= EXT4_BG_BLOCK_BITMAP_CSUM_HI_END) {
0072 hi = le16_to_cpu(gdp->bg_block_bitmap_csum_hi);
0073 provided |= (hi << 16);
0074 } else
0075 calculated &= 0xFFFF;
0076
0077 if (provided == calculated)
0078 return 1;
0079
0080 return 0;
0081 }
0082
0083 void ext4_block_bitmap_csum_set(struct super_block *sb, ext4_group_t group,
0084 struct ext4_group_desc *gdp,
0085 struct buffer_head *bh)
0086 {
0087 int sz = EXT4_CLUSTERS_PER_GROUP(sb) / 8;
0088 __u32 csum;
0089 struct ext4_sb_info *sbi = EXT4_SB(sb);
0090
0091 if (!ext4_has_metadata_csum(sb))
0092 return;
0093
0094 csum = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)bh->b_data, sz);
0095 gdp->bg_block_bitmap_csum_lo = cpu_to_le16(csum & 0xFFFF);
0096 if (sbi->s_desc_size >= EXT4_BG_BLOCK_BITMAP_CSUM_HI_END)
0097 gdp->bg_block_bitmap_csum_hi = cpu_to_le16(csum >> 16);
0098 }