bitmap.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <linux/kernel.h>
  3. #include <linux/fs.h>
  4. #include <linux/buffer_head.h>
  5. #include <asm/div64.h>
  6. #include "omfs.h"
  7. unsigned long omfs_count_free(struct super_block *sb)
  8. {
  9. unsigned int i;
  10. unsigned long sum = 0;
  11. struct omfs_sb_info *sbi = OMFS_SB(sb);
  12. int nbits = sb->s_blocksize * 8;
  13. for (i = 0; i < sbi->s_imap_size; i++)
  14. sum += nbits - bitmap_weight(sbi->s_imap[i], nbits);
  15. return sum;
  16. }
  17. /*
  18. * Counts the run of zero bits starting at bit up to max.
  19. * It handles the case where a run might spill over a buffer.
  20. * Called with bitmap lock.
  21. */
  22. static int count_run(unsigned long **addr, int nbits,
  23. int addrlen, int bit, int max)
  24. {
  25. int count = 0;
  26. int x;
  27. for (; addrlen > 0; addrlen--, addr++) {
  28. x = find_next_bit(*addr, nbits, bit);
  29. count += x - bit;
  30. if (x < nbits || count > max)
  31. return min(count, max);
  32. bit = 0;
  33. }
  34. return min(count, max);
  35. }
  36. /*
  37. * Sets or clears the run of count bits starting with bit.
  38. * Called with bitmap lock.
  39. */
  40. static int set_run(struct super_block *sb, int map,
  41. int nbits, int bit, int count, int set)
  42. {
  43. int i;
  44. int err;
  45. struct buffer_head *bh;
  46. struct omfs_sb_info *sbi = OMFS_SB(sb);
  47. err = -ENOMEM;
  48. bh = sb_bread(sb, clus_to_blk(sbi, sbi->s_bitmap_ino) + map);
  49. if (!bh)
  50. goto out;
  51. for (i = 0; i < count; i++, bit++) {
  52. if (bit >= nbits) {
  53. bit = 0;
  54. map++;
  55. mark_buffer_dirty(bh);
  56. brelse(bh);
  57. bh = sb_bread(sb,
  58. clus_to_blk(sbi, sbi->s_bitmap_ino) + map);
  59. if (!bh)
  60. goto out;
  61. }
  62. if (set) {
  63. set_bit(bit, sbi->s_imap[map]);
  64. set_bit(bit, (unsigned long *)bh->b_data);
  65. } else {
  66. clear_bit(bit, sbi->s_imap[map]);
  67. clear_bit(bit, (unsigned long *)bh->b_data);
  68. }
  69. }
  70. mark_buffer_dirty(bh);
  71. brelse(bh);
  72. err = 0;
  73. out:
  74. return err;
  75. }
  76. /*
  77. * Tries to allocate exactly one block. Returns true if successful.
  78. */
  79. int omfs_allocate_block(struct super_block *sb, u64 block)
  80. {
  81. struct buffer_head *bh;
  82. struct omfs_sb_info *sbi = OMFS_SB(sb);
  83. int bits_per_entry = 8 * sb->s_blocksize;
  84. unsigned int map, bit;
  85. int ret = 0;
  86. u64 tmp;
  87. tmp = block;
  88. bit = do_div(tmp, bits_per_entry);
  89. map = tmp;
  90. mutex_lock(&sbi->s_bitmap_lock);
  91. if (map >= sbi->s_imap_size || test_and_set_bit(bit, sbi->s_imap[map]))
  92. goto out;
  93. if (sbi->s_bitmap_ino > 0) {
  94. bh = sb_bread(sb, clus_to_blk(sbi, sbi->s_bitmap_ino) + map);
  95. if (!bh)
  96. goto out;
  97. set_bit(bit, (unsigned long *)bh->b_data);
  98. mark_buffer_dirty(bh);
  99. brelse(bh);
  100. }
  101. ret = 1;
  102. out:
  103. mutex_unlock(&sbi->s_bitmap_lock);
  104. return ret;
  105. }
  106. /*
  107. * Tries to allocate a set of blocks. The request size depends on the
  108. * type: for inodes, we must allocate sbi->s_mirrors blocks, and for file
  109. * blocks, we try to allocate sbi->s_clustersize, but can always get away
  110. * with just one block.
  111. */
  112. int omfs_allocate_range(struct super_block *sb,
  113. int min_request,
  114. int max_request,
  115. u64 *return_block,
  116. int *return_size)
  117. {
  118. struct omfs_sb_info *sbi = OMFS_SB(sb);
  119. int bits_per_entry = 8 * sb->s_blocksize;
  120. int ret = 0;
  121. int i, run, bit;
  122. mutex_lock(&sbi->s_bitmap_lock);
  123. for (i = 0; i < sbi->s_imap_size; i++) {
  124. bit = 0;
  125. while (bit < bits_per_entry) {
  126. bit = find_next_zero_bit(sbi->s_imap[i], bits_per_entry,
  127. bit);
  128. if (bit == bits_per_entry)
  129. break;
  130. run = count_run(&sbi->s_imap[i], bits_per_entry,
  131. sbi->s_imap_size-i, bit, max_request);
  132. if (run >= min_request)
  133. goto found;
  134. bit += run;
  135. }
  136. }
  137. ret = -ENOSPC;
  138. goto out;
  139. found:
  140. *return_block = (u64) i * bits_per_entry + bit;
  141. *return_size = run;
  142. ret = set_run(sb, i, bits_per_entry, bit, run, 1);
  143. out:
  144. mutex_unlock(&sbi->s_bitmap_lock);
  145. return ret;
  146. }
  147. /*
  148. * Clears count bits starting at a given block.
  149. */
  150. int omfs_clear_range(struct super_block *sb, u64 block, int count)
  151. {
  152. struct omfs_sb_info *sbi = OMFS_SB(sb);
  153. int bits_per_entry = 8 * sb->s_blocksize;
  154. u64 tmp;
  155. unsigned int map, bit;
  156. int ret;
  157. tmp = block;
  158. bit = do_div(tmp, bits_per_entry);
  159. map = tmp;
  160. if (map >= sbi->s_imap_size)
  161. return 0;
  162. mutex_lock(&sbi->s_bitmap_lock);
  163. ret = set_run(sb, map, bits_per_entry, bit, count, 0);
  164. mutex_unlock(&sbi->s_bitmap_lock);
  165. return ret;
  166. }