xref: /OK3568_Linux_fs/kernel/fs/ext4/bitmap.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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