f63e028c638c2426136e4c300ccc0ec02bce2358
[releases.git] / bitmap.c
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(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_metadata_csum(sb))
28                 return 1;
29
30         provided = le16_to_cpu(gdp->bg_inode_bitmap_csum_lo);
31         calculated = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)bh->b_data, 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, ext4_group_t group,
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, sbi->s_csum_seed, (__u8 *)bh->b_data, 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, ext4_group_t group,
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, sbi->s_csum_seed, (__u8 *)bh->b_data, 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         if (provided == calculated)
78                 return 1;
79
80         return 0;
81 }
82
83 void ext4_block_bitmap_csum_set(struct super_block *sb, ext4_group_t group,
84                                 struct ext4_group_desc *gdp,
85                                 struct buffer_head *bh)
86 {
87         int sz = EXT4_CLUSTERS_PER_GROUP(sb) / 8;
88         __u32 csum;
89         struct ext4_sb_info *sbi = EXT4_SB(sb);
90
91         if (!ext4_has_metadata_csum(sb))
92                 return;
93
94         csum = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)bh->b_data, sz);
95         gdp->bg_block_bitmap_csum_lo = cpu_to_le16(csum & 0xFFFF);
96         if (sbi->s_desc_size >= EXT4_BG_BLOCK_BITMAP_CSUM_HI_END)
97                 gdp->bg_block_bitmap_csum_hi = cpu_to_le16(csum >> 16);
98 }