]> Pileus Git - ~andy/linux/blob - fs/ext4/bitmap.c
5813e7f2e2c64ec5b33dc3fff992a1208447f1dc
[~andy/linux] / 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 <linux/jbd2.h>
12 #include "ext4.h"
13
14 #ifdef EXT4FS_DEBUG
15
16 static const int nibblemap[] = {4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0};
17
18 unsigned int ext4_count_free(struct buffer_head *map, unsigned int numchars)
19 {
20         unsigned int i, sum = 0;
21
22         if (!map)
23                 return 0;
24         for (i = 0; i < numchars; i++)
25                 sum += nibblemap[map->b_data[i] & 0xf] +
26                         nibblemap[(map->b_data[i] >> 4) & 0xf];
27         return sum;
28 }
29
30 #endif  /*  EXT4FS_DEBUG  */
31
32 int ext4_inode_bitmap_csum_verify(struct super_block *sb, ext4_group_t group,
33                                   struct ext4_group_desc *gdp,
34                                   struct buffer_head *bh, int sz)
35 {
36         __u32 hi;
37         __u32 provided, calculated;
38         struct ext4_sb_info *sbi = EXT4_SB(sb);
39
40         if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
41                                         EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
42                 return 1;
43
44         provided = le16_to_cpu(gdp->bg_inode_bitmap_csum_lo);
45         calculated = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)bh->b_data, sz);
46         if (sbi->s_desc_size >= EXT4_BG_INODE_BITMAP_CSUM_HI_END) {
47                 hi = le16_to_cpu(gdp->bg_inode_bitmap_csum_hi);
48                 provided |= (hi << 16);
49         } else
50                 calculated &= 0xFFFF;
51
52         return provided == calculated;
53 }
54
55 void ext4_inode_bitmap_csum_set(struct super_block *sb, ext4_group_t group,
56                                 struct ext4_group_desc *gdp,
57                                 struct buffer_head *bh, int sz)
58 {
59         __u32 csum;
60         struct ext4_sb_info *sbi = EXT4_SB(sb);
61
62         if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
63                                         EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
64                 return;
65
66         csum = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)bh->b_data, sz);
67         gdp->bg_inode_bitmap_csum_lo = cpu_to_le16(csum & 0xFFFF);
68         if (sbi->s_desc_size >= EXT4_BG_INODE_BITMAP_CSUM_HI_END)
69                 gdp->bg_inode_bitmap_csum_hi = cpu_to_le16(csum >> 16);
70 }