GNU Linux-libre 4.9.308-gnu1
[releases.git] / fs / ext4 / bitmap.c
1 /*
2  *  linux/fs/ext4/bitmap.c
3  *
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)
8  */
9
10 #include <linux/buffer_head.h>
11 #include "ext4.h"
12
13 unsigned int ext4_count_free(char *bitmap, unsigned int numchars)
14 {
15         return numchars * BITS_PER_BYTE - memweight(bitmap, numchars);
16 }
17
18 int ext4_inode_bitmap_csum_verify(struct super_block *sb, ext4_group_t group,
19                                   struct ext4_group_desc *gdp,
20                                   struct buffer_head *bh, int sz)
21 {
22         __u32 hi;
23         __u32 provided, calculated;
24         struct ext4_sb_info *sbi = EXT4_SB(sb);
25
26         if (!ext4_has_metadata_csum(sb))
27                 return 1;
28
29         provided = le16_to_cpu(gdp->bg_inode_bitmap_csum_lo);
30         calculated = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)bh->b_data, sz);
31         if (sbi->s_desc_size >= EXT4_BG_INODE_BITMAP_CSUM_HI_END) {
32                 hi = le16_to_cpu(gdp->bg_inode_bitmap_csum_hi);
33                 provided |= (hi << 16);
34         } else
35                 calculated &= 0xFFFF;
36
37         return provided == calculated;
38 }
39
40 void ext4_inode_bitmap_csum_set(struct super_block *sb, ext4_group_t group,
41                                 struct ext4_group_desc *gdp,
42                                 struct buffer_head *bh, int sz)
43 {
44         __u32 csum;
45         struct ext4_sb_info *sbi = EXT4_SB(sb);
46
47         if (!ext4_has_metadata_csum(sb))
48                 return;
49
50         csum = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)bh->b_data, sz);
51         gdp->bg_inode_bitmap_csum_lo = cpu_to_le16(csum & 0xFFFF);
52         if (sbi->s_desc_size >= EXT4_BG_INODE_BITMAP_CSUM_HI_END)
53                 gdp->bg_inode_bitmap_csum_hi = cpu_to_le16(csum >> 16);
54 }
55
56 int ext4_block_bitmap_csum_verify(struct super_block *sb, ext4_group_t group,
57                                   struct ext4_group_desc *gdp,
58                                   struct buffer_head *bh)
59 {
60         __u32 hi;
61         __u32 provided, calculated;
62         struct ext4_sb_info *sbi = EXT4_SB(sb);
63         int sz = EXT4_CLUSTERS_PER_GROUP(sb) / 8;
64
65         if (!ext4_has_metadata_csum(sb))
66                 return 1;
67
68         provided = le16_to_cpu(gdp->bg_block_bitmap_csum_lo);
69         calculated = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)bh->b_data, sz);
70         if (sbi->s_desc_size >= EXT4_BG_BLOCK_BITMAP_CSUM_HI_END) {
71                 hi = le16_to_cpu(gdp->bg_block_bitmap_csum_hi);
72                 provided |= (hi << 16);
73         } else
74                 calculated &= 0xFFFF;
75
76         if (provided == calculated)
77                 return 1;
78
79         return 0;
80 }
81
82 void ext4_block_bitmap_csum_set(struct super_block *sb, ext4_group_t group,
83                                 struct ext4_group_desc *gdp,
84                                 struct buffer_head *bh)
85 {
86         int sz = EXT4_CLUSTERS_PER_GROUP(sb) / 8;
87         __u32 csum;
88         struct ext4_sb_info *sbi = EXT4_SB(sb);
89
90         if (!ext4_has_metadata_csum(sb))
91                 return;
92
93         csum = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)bh->b_data, sz);
94         gdp->bg_block_bitmap_csum_lo = cpu_to_le16(csum & 0xFFFF);
95         if (sbi->s_desc_size >= EXT4_BG_BLOCK_BITMAP_CSUM_HI_END)
96                 gdp->bg_block_bitmap_csum_hi = cpu_to_le16(csum >> 16);
97 }