bitmap.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * linux/fs/ext4/bitmap.c
  4. *
  5. * Copyright (C) 1992, 1993, 1994, 1995
  6. * Remy Card (card@masi.ibp.fr)
  7. * Laboratoire MASI - Institut Blaise Pascal
  8. * Universite Pierre et Marie Curie (Paris VI)
  9. */
  10. #include <linux/buffer_head.h>
  11. #include "ext4.h"
  12. unsigned int ext4_count_free(char *bitmap, unsigned int numchars)
  13. {
  14. return numchars * BITS_PER_BYTE - memweight(bitmap, numchars);
  15. }
  16. int ext4_inode_bitmap_csum_verify(struct super_block *sb, ext4_group_t group,
  17. struct ext4_group_desc *gdp,
  18. struct buffer_head *bh, int sz)
  19. {
  20. __u32 hi;
  21. __u32 provided, calculated;
  22. struct ext4_sb_info *sbi = EXT4_SB(sb);
  23. if (!ext4_has_metadata_csum(sb))
  24. return 1;
  25. provided = le16_to_cpu(gdp->bg_inode_bitmap_csum_lo);
  26. calculated = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)bh->b_data, sz);
  27. if (sbi->s_desc_size >= EXT4_BG_INODE_BITMAP_CSUM_HI_END) {
  28. hi = le16_to_cpu(gdp->bg_inode_bitmap_csum_hi);
  29. provided |= (hi << 16);
  30. } else
  31. calculated &= 0xFFFF;
  32. return provided == calculated;
  33. }
  34. void ext4_inode_bitmap_csum_set(struct super_block *sb, ext4_group_t group,
  35. struct ext4_group_desc *gdp,
  36. struct buffer_head *bh, int sz)
  37. {
  38. __u32 csum;
  39. struct ext4_sb_info *sbi = EXT4_SB(sb);
  40. if (!ext4_has_metadata_csum(sb))
  41. return;
  42. csum = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)bh->b_data, sz);
  43. gdp->bg_inode_bitmap_csum_lo = cpu_to_le16(csum & 0xFFFF);
  44. if (sbi->s_desc_size >= EXT4_BG_INODE_BITMAP_CSUM_HI_END)
  45. gdp->bg_inode_bitmap_csum_hi = cpu_to_le16(csum >> 16);
  46. }
  47. int ext4_block_bitmap_csum_verify(struct super_block *sb, ext4_group_t group,
  48. struct ext4_group_desc *gdp,
  49. struct buffer_head *bh)
  50. {
  51. __u32 hi;
  52. __u32 provided, calculated;
  53. struct ext4_sb_info *sbi = EXT4_SB(sb);
  54. int sz = EXT4_CLUSTERS_PER_GROUP(sb) / 8;
  55. if (!ext4_has_metadata_csum(sb))
  56. return 1;
  57. provided = le16_to_cpu(gdp->bg_block_bitmap_csum_lo);
  58. calculated = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)bh->b_data, sz);
  59. if (sbi->s_desc_size >= EXT4_BG_BLOCK_BITMAP_CSUM_HI_END) {
  60. hi = le16_to_cpu(gdp->bg_block_bitmap_csum_hi);
  61. provided |= (hi << 16);
  62. } else
  63. calculated &= 0xFFFF;
  64. if (provided == calculated)
  65. return 1;
  66. return 0;
  67. }
  68. void ext4_block_bitmap_csum_set(struct super_block *sb, ext4_group_t group,
  69. struct ext4_group_desc *gdp,
  70. struct buffer_head *bh)
  71. {
  72. int sz = EXT4_CLUSTERS_PER_GROUP(sb) / 8;
  73. __u32 csum;
  74. struct ext4_sb_info *sbi = EXT4_SB(sb);
  75. if (!ext4_has_metadata_csum(sb))
  76. return;
  77. csum = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)bh->b_data, sz);
  78. gdp->bg_block_bitmap_csum_lo = cpu_to_le16(csum & 0xFFFF);
  79. if (sbi->s_desc_size >= EXT4_BG_BLOCK_BITMAP_CSUM_HI_END)
  80. gdp->bg_block_bitmap_csum_hi = cpu_to_le16(csum >> 16);
  81. }