1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * linux/fs/affs/bitmap.c 4 * 5 * (c) 1996 Hans-Joachim Widmaier 6 * 7 * bitmap.c contains the code that handles all bitmap related stuff - 8 * block allocation, deallocation, calculation of free space. 9 */ 10 11 #include <linux/slab.h> 12 #include "affs.h" 13 14 u32 15 affs_count_free_blocks(struct super_block *sb) 16 { 17 struct affs_bm_info *bm; 18 u32 free; 19 int i; 20 21 pr_debug("%s()\n", __func__); 22 23 if (sb_rdonly(sb)) 24 return 0; 25 26 mutex_lock(&AFFS_SB(sb)->s_bmlock); 27 28 bm = AFFS_SB(sb)->s_bitmap; 29 free = 0; 30 for (i = AFFS_SB(sb)->s_bmap_count; i > 0; bm++, i--) 31 free += bm->bm_free; 32 33 mutex_unlock(&AFFS_SB(sb)->s_bmlock); 34 35 return free; 36 } 37 38 void 39 affs_free_block(struct super_block *sb, u32 block) 40 { 41 struct affs_sb_info *sbi = AFFS_SB(sb); 42 struct affs_bm_info *bm; 43 struct buffer_head *bh; 44 u32 blk, bmap, bit, mask, tmp; 45 __be32 *data; 46 47 pr_debug("%s(%u)\n", __func__, block); 48 49 if (block > sbi->s_partition_size) 50 goto err_range; 51 52 blk = block - sbi->s_reserved; 53 bmap = blk / sbi->s_bmap_bits; 54 bit = blk % sbi->s_bmap_bits; 55 bm = &sbi->s_bitmap[bmap]; 56 57 mutex_lock(&sbi->s_bmlock); 58 59 bh = sbi->s_bmap_bh; 60 if (sbi->s_last_bmap != bmap) { 61 affs_brelse(bh); 62 bh = affs_bread(sb, bm->bm_key); 63 if (!bh) 64 goto err_bh_read; 65 sbi->s_bmap_bh = bh; 66 sbi->s_last_bmap = bmap; 67 } 68 69 mask = 1 << (bit & 31); 70 data = (__be32 *)bh->b_data + bit / 32 + 1; 71 72 /* mark block free */ 73 tmp = be32_to_cpu(*data); 74 if (tmp & mask) 75 goto err_free; 76 *data = cpu_to_be32(tmp | mask); 77 78 /* fix checksum */ 79 tmp = be32_to_cpu(*(__be32 *)bh->b_data); 80 *(__be32 *)bh->b_data = cpu_to_be32(tmp - mask); 81 82 mark_buffer_dirty(bh); 83 affs_mark_sb_dirty(sb); 84 bm->bm_free++; 85 86 mutex_unlock(&sbi->s_bmlock); 87 return; 88 89 err_free: 90 affs_warning(sb,"affs_free_block","Trying to free block %u which is already free", block); 91 mutex_unlock(&sbi->s_bmlock); 92 return; 93 94 err_bh_read: 95 affs_error(sb,"affs_free_block","Cannot read bitmap block %u", bm->bm_key); 96 sbi->s_bmap_bh = NULL; 97 sbi->s_last_bmap = ~0; 98 mutex_unlock(&sbi->s_bmlock); 99 return; 100 101 err_range: 102 affs_error(sb, "affs_free_block","Block %u outside partition", block); 103 } 104 105 /* 106 * Allocate a block in the given allocation zone. 107 * Since we have to byte-swap the bitmap on little-endian 108 * machines, this is rather expensive. Therefore we will 109 * preallocate up to 16 blocks from the same word, if 110 * possible. We are not doing preallocations in the 111 * header zone, though. 112 */ 113 114 u32 115 affs_alloc_block(struct inode *inode, u32 goal) 116 { 117 struct super_block *sb; 118 struct affs_sb_info *sbi; 119 struct affs_bm_info *bm; 120 struct buffer_head *bh; 121 __be32 *data, *enddata; 122 u32 blk, bmap, bit, mask, mask2, tmp; 123 int i; 124 125 sb = inode->i_sb; 126 sbi = AFFS_SB(sb); 127 128 pr_debug("balloc(inode=%lu,goal=%u): ", inode->i_ino, goal); 129 130 if (AFFS_I(inode)->i_pa_cnt) { 131 pr_debug("%d\n", AFFS_I(inode)->i_lastalloc+1); 132 AFFS_I(inode)->i_pa_cnt--; 133 return ++AFFS_I(inode)->i_lastalloc; 134 } 135 136 if (!goal || goal > sbi->s_partition_size) { 137 if (goal) 138 affs_warning(sb, "affs_balloc", "invalid goal %d", goal); 139 //if (!AFFS_I(inode)->i_last_block) 140 // affs_warning(sb, "affs_balloc", "no last alloc block"); 141 goal = sbi->s_reserved; 142 } 143 144 blk = goal - sbi->s_reserved; 145 bmap = blk / sbi->s_bmap_bits; 146 bm = &sbi->s_bitmap[bmap]; 147 148 mutex_lock(&sbi->s_bmlock); 149 150 if (bm->bm_free) 151 goto find_bmap_bit; 152 153 find_bmap: 154 /* search for the next bmap buffer with free bits */ 155 i = sbi->s_bmap_count; 156 do { 157 if (--i < 0) 158 goto err_full; 159 bmap++; 160 bm++; 161 if (bmap < sbi->s_bmap_count) 162 continue; 163 /* restart search at zero */ 164 bmap = 0; 165 bm = sbi->s_bitmap; 166 } while (!bm->bm_free); 167 blk = bmap * sbi->s_bmap_bits; 168 169 find_bmap_bit: 170 171 bh = sbi->s_bmap_bh; 172 if (sbi->s_last_bmap != bmap) { 173 affs_brelse(bh); 174 bh = affs_bread(sb, bm->bm_key); 175 if (!bh) 176 goto err_bh_read; 177 sbi->s_bmap_bh = bh; 178 sbi->s_last_bmap = bmap; 179 } 180 181 /* find an unused block in this bitmap block */ 182 bit = blk % sbi->s_bmap_bits; 183 data = (__be32 *)bh->b_data + bit / 32 + 1; 184 enddata = (__be32 *)((u8 *)bh->b_data + sb->s_blocksize); 185 mask = ~0UL << (bit & 31); 186 blk &= ~31UL; 187 188 tmp = be32_to_cpu(*data); 189 if (tmp & mask) 190 goto find_bit; 191 192 /* scan the rest of the buffer */ 193 do { 194 blk += 32; 195 if (++data >= enddata) 196 /* didn't find something, can only happen 197 * if scan didn't start at 0, try next bmap 198 */ 199 goto find_bmap; 200 } while (!*data); 201 tmp = be32_to_cpu(*data); 202 mask = ~0; 203 204 find_bit: 205 /* finally look for a free bit in the word */ 206 bit = ffs(tmp & mask) - 1; 207 blk += bit + sbi->s_reserved; 208 mask2 = mask = 1 << (bit & 31); 209 AFFS_I(inode)->i_lastalloc = blk; 210 211 /* prealloc as much as possible within this word */ 212 while ((mask2 <<= 1)) { 213 if (!(tmp & mask2)) 214 break; 215 AFFS_I(inode)->i_pa_cnt++; 216 mask |= mask2; 217 } 218 bm->bm_free -= AFFS_I(inode)->i_pa_cnt + 1; 219 220 *data = cpu_to_be32(tmp & ~mask); 221 222 /* fix checksum */ 223 tmp = be32_to_cpu(*(__be32 *)bh->b_data); 224 *(__be32 *)bh->b_data = cpu_to_be32(tmp + mask); 225 226 mark_buffer_dirty(bh); 227 affs_mark_sb_dirty(sb); 228 229 mutex_unlock(&sbi->s_bmlock); 230 231 pr_debug("%d\n", blk); 232 return blk; 233 234 err_bh_read: 235 affs_error(sb,"affs_read_block","Cannot read bitmap block %u", bm->bm_key); 236 sbi->s_bmap_bh = NULL; 237 sbi->s_last_bmap = ~0; 238 err_full: 239 mutex_unlock(&sbi->s_bmlock); 240 pr_debug("failed\n"); 241 return 0; 242 } 243 244 int affs_init_bitmap(struct super_block *sb, int *flags) 245 { 246 struct affs_bm_info *bm; 247 struct buffer_head *bmap_bh = NULL, *bh = NULL; 248 __be32 *bmap_blk; 249 u32 size, blk, end, offset, mask; 250 int i, res = 0; 251 struct affs_sb_info *sbi = AFFS_SB(sb); 252 253 if (*flags & SB_RDONLY) 254 return 0; 255 256 if (!AFFS_ROOT_TAIL(sb, sbi->s_root_bh)->bm_flag) { 257 pr_notice("Bitmap invalid - mounting %s read only\n", sb->s_id); 258 *flags |= SB_RDONLY; 259 return 0; 260 } 261 262 sbi->s_last_bmap = ~0; 263 sbi->s_bmap_bh = NULL; 264 sbi->s_bmap_bits = sb->s_blocksize * 8 - 32; 265 sbi->s_bmap_count = (sbi->s_partition_size - sbi->s_reserved + 266 sbi->s_bmap_bits - 1) / sbi->s_bmap_bits; 267 size = sbi->s_bmap_count * sizeof(*bm); 268 bm = sbi->s_bitmap = kzalloc(size, GFP_KERNEL); 269 if (!sbi->s_bitmap) { 270 pr_err("Bitmap allocation failed\n"); 271 return -ENOMEM; 272 } 273 274 bmap_blk = (__be32 *)sbi->s_root_bh->b_data; 275 blk = sb->s_blocksize / 4 - 49; 276 end = blk + 25; 277 278 for (i = sbi->s_bmap_count; i > 0; bm++, i--) { 279 affs_brelse(bh); 280 281 bm->bm_key = be32_to_cpu(bmap_blk[blk]); 282 bh = affs_bread(sb, bm->bm_key); 283 if (!bh) { 284 pr_err("Cannot read bitmap\n"); 285 res = -EIO; 286 goto out; 287 } 288 if (affs_checksum_block(sb, bh)) { 289 pr_warn("Bitmap %u invalid - mounting %s read only.\n", 290 bm->bm_key, sb->s_id); 291 *flags |= SB_RDONLY; 292 goto out; 293 } 294 pr_debug("read bitmap block %d: %d\n", blk, bm->bm_key); 295 bm->bm_free = memweight(bh->b_data + 4, sb->s_blocksize - 4); 296 297 /* Don't try read the extension if this is the last block, 298 * but we also need the right bm pointer below 299 */ 300 if (++blk < end || i == 1) 301 continue; 302 if (bmap_bh) 303 affs_brelse(bmap_bh); 304 bmap_bh = affs_bread(sb, be32_to_cpu(bmap_blk[blk])); 305 if (!bmap_bh) { 306 pr_err("Cannot read bitmap extension\n"); 307 res = -EIO; 308 goto out; 309 } 310 bmap_blk = (__be32 *)bmap_bh->b_data; 311 blk = 0; 312 end = sb->s_blocksize / 4 - 1; 313 } 314 315 offset = (sbi->s_partition_size - sbi->s_reserved) % sbi->s_bmap_bits; 316 mask = ~(0xFFFFFFFFU << (offset & 31)); 317 pr_debug("last word: %d %d %d\n", offset, offset / 32 + 1, mask); 318 offset = offset / 32 + 1; 319 320 if (mask) { 321 u32 old, new; 322 323 /* Mark unused bits in the last word as allocated */ 324 old = be32_to_cpu(((__be32 *)bh->b_data)[offset]); 325 new = old & mask; 326 //if (old != new) { 327 ((__be32 *)bh->b_data)[offset] = cpu_to_be32(new); 328 /* fix checksum */ 329 //new -= old; 330 //old = be32_to_cpu(*(__be32 *)bh->b_data); 331 //*(__be32 *)bh->b_data = cpu_to_be32(old - new); 332 //mark_buffer_dirty(bh); 333 //} 334 /* correct offset for the bitmap count below */ 335 //offset++; 336 } 337 while (++offset < sb->s_blocksize / 4) 338 ((__be32 *)bh->b_data)[offset] = 0; 339 ((__be32 *)bh->b_data)[0] = 0; 340 ((__be32 *)bh->b_data)[0] = cpu_to_be32(-affs_checksum_block(sb, bh)); 341 mark_buffer_dirty(bh); 342 343 /* recalculate bitmap count for last block */ 344 bm--; 345 bm->bm_free = memweight(bh->b_data + 4, sb->s_blocksize - 4); 346 347 out: 348 affs_brelse(bh); 349 affs_brelse(bmap_bh); 350 return res; 351 } 352 353 void affs_free_bitmap(struct super_block *sb) 354 { 355 struct affs_sb_info *sbi = AFFS_SB(sb); 356 357 if (!sbi->s_bitmap) 358 return; 359 360 affs_brelse(sbi->s_bmap_bh); 361 sbi->s_bmap_bh = NULL; 362 sbi->s_last_bmap = ~0; 363 kfree(sbi->s_bitmap); 364 sbi->s_bitmap = NULL; 365 } 366
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.