2 * linux/fs/ext4/bitmap.c
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)
10 #include <linux/buffer_head.h>
11 #include <linux/jbd2.h>
16 static const int nibblemap
[] = {4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0};
18 unsigned int ext4_count_free(char *bitmap
, unsigned int numchars
)
20 unsigned int i
, sum
= 0;
22 for (i
= 0; i
< numchars
; i
++)
23 sum
+= nibblemap
[bitmap
[i
] & 0xf] +
24 nibblemap
[(bitmap
[i
] >> 4) & 0xf];
28 #endif /* EXT4FS_DEBUG */
30 int ext4_inode_bitmap_csum_verify(struct super_block
*sb
, ext4_group_t group
,
31 struct ext4_group_desc
*gdp
,
32 struct buffer_head
*bh
, int sz
)
35 __u32 provided
, calculated
;
36 struct ext4_sb_info
*sbi
= EXT4_SB(sb
);
38 if (!EXT4_HAS_RO_COMPAT_FEATURE(sb
,
39 EXT4_FEATURE_RO_COMPAT_METADATA_CSUM
))
42 provided
= le16_to_cpu(gdp
->bg_inode_bitmap_csum_lo
);
43 calculated
= ext4_chksum(sbi
, sbi
->s_csum_seed
, (__u8
*)bh
->b_data
, sz
);
44 if (sbi
->s_desc_size
>= EXT4_BG_INODE_BITMAP_CSUM_HI_END
) {
45 hi
= le16_to_cpu(gdp
->bg_inode_bitmap_csum_hi
);
46 provided
|= (hi
<< 16);
50 return provided
== calculated
;
53 void ext4_inode_bitmap_csum_set(struct super_block
*sb
, ext4_group_t group
,
54 struct ext4_group_desc
*gdp
,
55 struct buffer_head
*bh
, int sz
)
58 struct ext4_sb_info
*sbi
= EXT4_SB(sb
);
60 if (!EXT4_HAS_RO_COMPAT_FEATURE(sb
,
61 EXT4_FEATURE_RO_COMPAT_METADATA_CSUM
))
64 csum
= ext4_chksum(sbi
, sbi
->s_csum_seed
, (__u8
*)bh
->b_data
, sz
);
65 gdp
->bg_inode_bitmap_csum_lo
= cpu_to_le16(csum
& 0xFFFF);
66 if (sbi
->s_desc_size
>= EXT4_BG_INODE_BITMAP_CSUM_HI_END
)
67 gdp
->bg_inode_bitmap_csum_hi
= cpu_to_le16(csum
>> 16);
70 int ext4_block_bitmap_csum_verify(struct super_block
*sb
, ext4_group_t group
,
71 struct ext4_group_desc
*gdp
,
72 struct buffer_head
*bh
, int sz
)
75 __u32 provided
, calculated
;
76 struct ext4_sb_info
*sbi
= EXT4_SB(sb
);
78 if (!EXT4_HAS_RO_COMPAT_FEATURE(sb
,
79 EXT4_FEATURE_RO_COMPAT_METADATA_CSUM
))
82 provided
= le16_to_cpu(gdp
->bg_block_bitmap_csum_lo
);
83 calculated
= ext4_chksum(sbi
, sbi
->s_csum_seed
, (__u8
*)bh
->b_data
, sz
);
84 if (sbi
->s_desc_size
>= EXT4_BG_BLOCK_BITMAP_CSUM_HI_END
) {
85 hi
= le16_to_cpu(gdp
->bg_block_bitmap_csum_hi
);
86 provided
|= (hi
<< 16);
90 if (provided
== calculated
)
93 ext4_error(sb
, "Bad block bitmap checksum: block_group = %u", group
);
97 void ext4_block_bitmap_csum_set(struct super_block
*sb
, ext4_group_t group
,
98 struct ext4_group_desc
*gdp
,
99 struct buffer_head
*bh
, int sz
)
102 struct ext4_sb_info
*sbi
= EXT4_SB(sb
);
104 if (!EXT4_HAS_RO_COMPAT_FEATURE(sb
,
105 EXT4_FEATURE_RO_COMPAT_METADATA_CSUM
))
108 csum
= ext4_chksum(sbi
, sbi
->s_csum_seed
, (__u8
*)bh
->b_data
, sz
);
109 gdp
->bg_block_bitmap_csum_lo
= cpu_to_le16(csum
& 0xFFFF);
110 if (sbi
->s_desc_size
>= EXT4_BG_BLOCK_BITMAP_CSUM_HI_END
)
111 gdp
->bg_block_bitmap_csum_hi
= cpu_to_le16(csum
>> 16);