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(struct buffer_head
*map
, unsigned int numchars
)
20 unsigned int i
, sum
= 0;
24 for (i
= 0; i
< numchars
; i
++)
25 sum
+= nibblemap
[map
->b_data
[i
] & 0xf] +
26 nibblemap
[(map
->b_data
[i
] >> 4) & 0xf];
30 #endif /* EXT4FS_DEBUG */
32 int ext4_inode_bitmap_csum_verify(struct super_block
*sb
, ext4_group_t group
,
33 struct ext4_group_desc
*gdp
,
34 struct buffer_head
*bh
, int sz
)
37 __u32 provided
, calculated
;
38 struct ext4_sb_info
*sbi
= EXT4_SB(sb
);
40 if (!EXT4_HAS_RO_COMPAT_FEATURE(sb
,
41 EXT4_FEATURE_RO_COMPAT_METADATA_CSUM
))
44 provided
= le16_to_cpu(gdp
->bg_inode_bitmap_csum_lo
);
45 calculated
= ext4_chksum(sbi
, sbi
->s_csum_seed
, (__u8
*)bh
->b_data
, sz
);
46 if (sbi
->s_desc_size
>= EXT4_BG_INODE_BITMAP_CSUM_HI_END
) {
47 hi
= le16_to_cpu(gdp
->bg_inode_bitmap_csum_hi
);
48 provided
|= (hi
<< 16);
52 return provided
== calculated
;
55 void ext4_inode_bitmap_csum_set(struct super_block
*sb
, ext4_group_t group
,
56 struct ext4_group_desc
*gdp
,
57 struct buffer_head
*bh
, int sz
)
60 struct ext4_sb_info
*sbi
= EXT4_SB(sb
);
62 if (!EXT4_HAS_RO_COMPAT_FEATURE(sb
,
63 EXT4_FEATURE_RO_COMPAT_METADATA_CSUM
))
66 csum
= ext4_chksum(sbi
, sbi
->s_csum_seed
, (__u8
*)bh
->b_data
, sz
);
67 gdp
->bg_inode_bitmap_csum_lo
= cpu_to_le16(csum
& 0xFFFF);
68 if (sbi
->s_desc_size
>= EXT4_BG_INODE_BITMAP_CSUM_HI_END
)
69 gdp
->bg_inode_bitmap_csum_hi
= cpu_to_le16(csum
>> 16);
72 int ext4_block_bitmap_csum_verify(struct super_block
*sb
, ext4_group_t group
,
73 struct ext4_group_desc
*gdp
,
74 struct buffer_head
*bh
, int sz
)
77 __u32 provided
, calculated
;
78 struct ext4_sb_info
*sbi
= EXT4_SB(sb
);
80 if (!EXT4_HAS_RO_COMPAT_FEATURE(sb
,
81 EXT4_FEATURE_RO_COMPAT_METADATA_CSUM
))
84 provided
= le16_to_cpu(gdp
->bg_block_bitmap_csum_lo
);
85 calculated
= ext4_chksum(sbi
, sbi
->s_csum_seed
, (__u8
*)bh
->b_data
, sz
);
86 if (sbi
->s_desc_size
>= EXT4_BG_BLOCK_BITMAP_CSUM_HI_END
) {
87 hi
= le16_to_cpu(gdp
->bg_block_bitmap_csum_hi
);
88 provided
|= (hi
<< 16);
92 if (provided
== calculated
)
95 ext4_error(sb
, "Bad block bitmap checksum: block_group = %u", group
);
99 void ext4_block_bitmap_csum_set(struct super_block
*sb
, ext4_group_t group
,
100 struct ext4_group_desc
*gdp
,
101 struct buffer_head
*bh
, int sz
)
104 struct ext4_sb_info
*sbi
= EXT4_SB(sb
);
106 if (!EXT4_HAS_RO_COMPAT_FEATURE(sb
,
107 EXT4_FEATURE_RO_COMPAT_METADATA_CSUM
))
110 csum
= ext4_chksum(sbi
, sbi
->s_csum_seed
, (__u8
*)bh
->b_data
, sz
);
111 gdp
->bg_block_bitmap_csum_lo
= cpu_to_le16(csum
& 0xFFFF);
112 if (sbi
->s_desc_size
>= EXT4_BG_BLOCK_BITMAP_CSUM_HI_END
)
113 gdp
->bg_block_bitmap_csum_hi
= cpu_to_le16(csum
>> 16);