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