bitmap.c 2.6 KB

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