bitmap.c 2.66 KB
Newer Older
1
/*
2
 *  linux/fs/ext4/bitmap.c
3 4 5 6 7 8 9 10
 *
 * Copyright (C) 1992, 1993, 1994, 1995
 * Remy Card (card@masi.ibp.fr)
 * Laboratoire MASI - Institut Blaise Pascal
 * Universite Pierre et Marie Curie (Paris VI)
 */

#include <linux/buffer_head.h>
11
#include <linux/jbd2.h>
12
#include "ext4.h"
13

14
unsigned int ext4_count_free(char *bitmap, unsigned int numchars)
15
{
Akinobu Mita's avatar
Akinobu Mita committed
16
	return numchars * BITS_PER_BYTE - memweight(bitmap, numchars);
17 18
}

19 20 21 22 23 24 25 26
int ext4_inode_bitmap_csum_verify(struct super_block *sb, ext4_group_t group,
				  struct ext4_group_desc *gdp,
				  struct buffer_head *bh, int sz)
{
	__u32 hi;
	__u32 provided, calculated;
	struct ext4_sb_info *sbi = EXT4_SB(sb);

27
	if (!ext4_has_metadata_csum(sb))
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
		return 1;

	provided = le16_to_cpu(gdp->bg_inode_bitmap_csum_lo);
	calculated = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)bh->b_data, sz);
	if (sbi->s_desc_size >= EXT4_BG_INODE_BITMAP_CSUM_HI_END) {
		hi = le16_to_cpu(gdp->bg_inode_bitmap_csum_hi);
		provided |= (hi << 16);
	} else
		calculated &= 0xFFFF;

	return provided == calculated;
}

void ext4_inode_bitmap_csum_set(struct super_block *sb, ext4_group_t group,
				struct ext4_group_desc *gdp,
				struct buffer_head *bh, int sz)
{
	__u32 csum;
	struct ext4_sb_info *sbi = EXT4_SB(sb);

48
	if (!ext4_has_metadata_csum(sb))
49 50 51 52 53 54 55
		return;

	csum = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)bh->b_data, sz);
	gdp->bg_inode_bitmap_csum_lo = cpu_to_le16(csum & 0xFFFF);
	if (sbi->s_desc_size >= EXT4_BG_INODE_BITMAP_CSUM_HI_END)
		gdp->bg_inode_bitmap_csum_hi = cpu_to_le16(csum >> 16);
}
56 57 58

int ext4_block_bitmap_csum_verify(struct super_block *sb, ext4_group_t group,
				  struct ext4_group_desc *gdp,
59
				  struct buffer_head *bh)
60 61 62 63
{
	__u32 hi;
	__u32 provided, calculated;
	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 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
		return 1;

	provided = le16_to_cpu(gdp->bg_block_bitmap_csum_lo);
	calculated = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)bh->b_data, sz);
	if (sbi->s_desc_size >= EXT4_BG_BLOCK_BITMAP_CSUM_HI_END) {
		hi = le16_to_cpu(gdp->bg_block_bitmap_csum_hi);
		provided |= (hi << 16);
	} else
		calculated &= 0xFFFF;

	if (provided == calculated)
		return 1;

	return 0;
}

void ext4_block_bitmap_csum_set(struct super_block *sb, ext4_group_t group,
				struct ext4_group_desc *gdp,
85
				struct buffer_head *bh)
86
{
87
	int sz = EXT4_CLUSTERS_PER_GROUP(sb) / 8;
88 89 90
	__u32 csum;
	struct ext4_sb_info *sbi = EXT4_SB(sb);

91
	if (!ext4_has_metadata_csum(sb))
92 93 94 95 96 97 98
		return;

	csum = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)bh->b_data, sz);
	gdp->bg_block_bitmap_csum_lo = cpu_to_le16(csum & 0xFFFF);
	if (sbi->s_desc_size >= EXT4_BG_BLOCK_BITMAP_CSUM_HI_END)
		gdp->bg_block_bitmap_csum_hi = cpu_to_le16(csum >> 16);
}