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