18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * linux/fs/affs/bitmap.c 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * (c) 1996 Hans-Joachim Widmaier 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * bitmap.c contains the code that handles all bitmap related stuff - 88c2ecf20Sopenharmony_ci * block allocation, deallocation, calculation of free space. 98c2ecf20Sopenharmony_ci */ 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#include <linux/slab.h> 128c2ecf20Sopenharmony_ci#include "affs.h" 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ciu32 158c2ecf20Sopenharmony_ciaffs_count_free_blocks(struct super_block *sb) 168c2ecf20Sopenharmony_ci{ 178c2ecf20Sopenharmony_ci struct affs_bm_info *bm; 188c2ecf20Sopenharmony_ci u32 free; 198c2ecf20Sopenharmony_ci int i; 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci pr_debug("%s()\n", __func__); 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci if (sb_rdonly(sb)) 248c2ecf20Sopenharmony_ci return 0; 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci mutex_lock(&AFFS_SB(sb)->s_bmlock); 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci bm = AFFS_SB(sb)->s_bitmap; 298c2ecf20Sopenharmony_ci free = 0; 308c2ecf20Sopenharmony_ci for (i = AFFS_SB(sb)->s_bmap_count; i > 0; bm++, i--) 318c2ecf20Sopenharmony_ci free += bm->bm_free; 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci mutex_unlock(&AFFS_SB(sb)->s_bmlock); 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci return free; 368c2ecf20Sopenharmony_ci} 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_civoid 398c2ecf20Sopenharmony_ciaffs_free_block(struct super_block *sb, u32 block) 408c2ecf20Sopenharmony_ci{ 418c2ecf20Sopenharmony_ci struct affs_sb_info *sbi = AFFS_SB(sb); 428c2ecf20Sopenharmony_ci struct affs_bm_info *bm; 438c2ecf20Sopenharmony_ci struct buffer_head *bh; 448c2ecf20Sopenharmony_ci u32 blk, bmap, bit, mask, tmp; 458c2ecf20Sopenharmony_ci __be32 *data; 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci pr_debug("%s(%u)\n", __func__, block); 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci if (block > sbi->s_partition_size) 508c2ecf20Sopenharmony_ci goto err_range; 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci blk = block - sbi->s_reserved; 538c2ecf20Sopenharmony_ci bmap = blk / sbi->s_bmap_bits; 548c2ecf20Sopenharmony_ci bit = blk % sbi->s_bmap_bits; 558c2ecf20Sopenharmony_ci bm = &sbi->s_bitmap[bmap]; 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci mutex_lock(&sbi->s_bmlock); 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci bh = sbi->s_bmap_bh; 608c2ecf20Sopenharmony_ci if (sbi->s_last_bmap != bmap) { 618c2ecf20Sopenharmony_ci affs_brelse(bh); 628c2ecf20Sopenharmony_ci bh = affs_bread(sb, bm->bm_key); 638c2ecf20Sopenharmony_ci if (!bh) 648c2ecf20Sopenharmony_ci goto err_bh_read; 658c2ecf20Sopenharmony_ci sbi->s_bmap_bh = bh; 668c2ecf20Sopenharmony_ci sbi->s_last_bmap = bmap; 678c2ecf20Sopenharmony_ci } 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci mask = 1 << (bit & 31); 708c2ecf20Sopenharmony_ci data = (__be32 *)bh->b_data + bit / 32 + 1; 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci /* mark block free */ 738c2ecf20Sopenharmony_ci tmp = be32_to_cpu(*data); 748c2ecf20Sopenharmony_ci if (tmp & mask) 758c2ecf20Sopenharmony_ci goto err_free; 768c2ecf20Sopenharmony_ci *data = cpu_to_be32(tmp | mask); 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci /* fix checksum */ 798c2ecf20Sopenharmony_ci tmp = be32_to_cpu(*(__be32 *)bh->b_data); 808c2ecf20Sopenharmony_ci *(__be32 *)bh->b_data = cpu_to_be32(tmp - mask); 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci mark_buffer_dirty(bh); 838c2ecf20Sopenharmony_ci affs_mark_sb_dirty(sb); 848c2ecf20Sopenharmony_ci bm->bm_free++; 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci mutex_unlock(&sbi->s_bmlock); 878c2ecf20Sopenharmony_ci return; 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_cierr_free: 908c2ecf20Sopenharmony_ci affs_warning(sb,"affs_free_block","Trying to free block %u which is already free", block); 918c2ecf20Sopenharmony_ci mutex_unlock(&sbi->s_bmlock); 928c2ecf20Sopenharmony_ci return; 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_cierr_bh_read: 958c2ecf20Sopenharmony_ci affs_error(sb,"affs_free_block","Cannot read bitmap block %u", bm->bm_key); 968c2ecf20Sopenharmony_ci sbi->s_bmap_bh = NULL; 978c2ecf20Sopenharmony_ci sbi->s_last_bmap = ~0; 988c2ecf20Sopenharmony_ci mutex_unlock(&sbi->s_bmlock); 998c2ecf20Sopenharmony_ci return; 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_cierr_range: 1028c2ecf20Sopenharmony_ci affs_error(sb, "affs_free_block","Block %u outside partition", block); 1038c2ecf20Sopenharmony_ci} 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci/* 1068c2ecf20Sopenharmony_ci * Allocate a block in the given allocation zone. 1078c2ecf20Sopenharmony_ci * Since we have to byte-swap the bitmap on little-endian 1088c2ecf20Sopenharmony_ci * machines, this is rather expensive. Therefore we will 1098c2ecf20Sopenharmony_ci * preallocate up to 16 blocks from the same word, if 1108c2ecf20Sopenharmony_ci * possible. We are not doing preallocations in the 1118c2ecf20Sopenharmony_ci * header zone, though. 1128c2ecf20Sopenharmony_ci */ 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_ciu32 1158c2ecf20Sopenharmony_ciaffs_alloc_block(struct inode *inode, u32 goal) 1168c2ecf20Sopenharmony_ci{ 1178c2ecf20Sopenharmony_ci struct super_block *sb; 1188c2ecf20Sopenharmony_ci struct affs_sb_info *sbi; 1198c2ecf20Sopenharmony_ci struct affs_bm_info *bm; 1208c2ecf20Sopenharmony_ci struct buffer_head *bh; 1218c2ecf20Sopenharmony_ci __be32 *data, *enddata; 1228c2ecf20Sopenharmony_ci u32 blk, bmap, bit, mask, mask2, tmp; 1238c2ecf20Sopenharmony_ci int i; 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_ci sb = inode->i_sb; 1268c2ecf20Sopenharmony_ci sbi = AFFS_SB(sb); 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci pr_debug("balloc(inode=%lu,goal=%u): ", inode->i_ino, goal); 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci if (AFFS_I(inode)->i_pa_cnt) { 1318c2ecf20Sopenharmony_ci pr_debug("%d\n", AFFS_I(inode)->i_lastalloc+1); 1328c2ecf20Sopenharmony_ci AFFS_I(inode)->i_pa_cnt--; 1338c2ecf20Sopenharmony_ci return ++AFFS_I(inode)->i_lastalloc; 1348c2ecf20Sopenharmony_ci } 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_ci if (!goal || goal > sbi->s_partition_size) { 1378c2ecf20Sopenharmony_ci if (goal) 1388c2ecf20Sopenharmony_ci affs_warning(sb, "affs_balloc", "invalid goal %d", goal); 1398c2ecf20Sopenharmony_ci //if (!AFFS_I(inode)->i_last_block) 1408c2ecf20Sopenharmony_ci // affs_warning(sb, "affs_balloc", "no last alloc block"); 1418c2ecf20Sopenharmony_ci goal = sbi->s_reserved; 1428c2ecf20Sopenharmony_ci } 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_ci blk = goal - sbi->s_reserved; 1458c2ecf20Sopenharmony_ci bmap = blk / sbi->s_bmap_bits; 1468c2ecf20Sopenharmony_ci bm = &sbi->s_bitmap[bmap]; 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci mutex_lock(&sbi->s_bmlock); 1498c2ecf20Sopenharmony_ci 1508c2ecf20Sopenharmony_ci if (bm->bm_free) 1518c2ecf20Sopenharmony_ci goto find_bmap_bit; 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_cifind_bmap: 1548c2ecf20Sopenharmony_ci /* search for the next bmap buffer with free bits */ 1558c2ecf20Sopenharmony_ci i = sbi->s_bmap_count; 1568c2ecf20Sopenharmony_ci do { 1578c2ecf20Sopenharmony_ci if (--i < 0) 1588c2ecf20Sopenharmony_ci goto err_full; 1598c2ecf20Sopenharmony_ci bmap++; 1608c2ecf20Sopenharmony_ci bm++; 1618c2ecf20Sopenharmony_ci if (bmap < sbi->s_bmap_count) 1628c2ecf20Sopenharmony_ci continue; 1638c2ecf20Sopenharmony_ci /* restart search at zero */ 1648c2ecf20Sopenharmony_ci bmap = 0; 1658c2ecf20Sopenharmony_ci bm = sbi->s_bitmap; 1668c2ecf20Sopenharmony_ci } while (!bm->bm_free); 1678c2ecf20Sopenharmony_ci blk = bmap * sbi->s_bmap_bits; 1688c2ecf20Sopenharmony_ci 1698c2ecf20Sopenharmony_cifind_bmap_bit: 1708c2ecf20Sopenharmony_ci 1718c2ecf20Sopenharmony_ci bh = sbi->s_bmap_bh; 1728c2ecf20Sopenharmony_ci if (sbi->s_last_bmap != bmap) { 1738c2ecf20Sopenharmony_ci affs_brelse(bh); 1748c2ecf20Sopenharmony_ci bh = affs_bread(sb, bm->bm_key); 1758c2ecf20Sopenharmony_ci if (!bh) 1768c2ecf20Sopenharmony_ci goto err_bh_read; 1778c2ecf20Sopenharmony_ci sbi->s_bmap_bh = bh; 1788c2ecf20Sopenharmony_ci sbi->s_last_bmap = bmap; 1798c2ecf20Sopenharmony_ci } 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_ci /* find an unused block in this bitmap block */ 1828c2ecf20Sopenharmony_ci bit = blk % sbi->s_bmap_bits; 1838c2ecf20Sopenharmony_ci data = (__be32 *)bh->b_data + bit / 32 + 1; 1848c2ecf20Sopenharmony_ci enddata = (__be32 *)((u8 *)bh->b_data + sb->s_blocksize); 1858c2ecf20Sopenharmony_ci mask = ~0UL << (bit & 31); 1868c2ecf20Sopenharmony_ci blk &= ~31UL; 1878c2ecf20Sopenharmony_ci 1888c2ecf20Sopenharmony_ci tmp = be32_to_cpu(*data); 1898c2ecf20Sopenharmony_ci if (tmp & mask) 1908c2ecf20Sopenharmony_ci goto find_bit; 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_ci /* scan the rest of the buffer */ 1938c2ecf20Sopenharmony_ci do { 1948c2ecf20Sopenharmony_ci blk += 32; 1958c2ecf20Sopenharmony_ci if (++data >= enddata) 1968c2ecf20Sopenharmony_ci /* didn't find something, can only happen 1978c2ecf20Sopenharmony_ci * if scan didn't start at 0, try next bmap 1988c2ecf20Sopenharmony_ci */ 1998c2ecf20Sopenharmony_ci goto find_bmap; 2008c2ecf20Sopenharmony_ci } while (!*data); 2018c2ecf20Sopenharmony_ci tmp = be32_to_cpu(*data); 2028c2ecf20Sopenharmony_ci mask = ~0; 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_cifind_bit: 2058c2ecf20Sopenharmony_ci /* finally look for a free bit in the word */ 2068c2ecf20Sopenharmony_ci bit = ffs(tmp & mask) - 1; 2078c2ecf20Sopenharmony_ci blk += bit + sbi->s_reserved; 2088c2ecf20Sopenharmony_ci mask2 = mask = 1 << (bit & 31); 2098c2ecf20Sopenharmony_ci AFFS_I(inode)->i_lastalloc = blk; 2108c2ecf20Sopenharmony_ci 2118c2ecf20Sopenharmony_ci /* prealloc as much as possible within this word */ 2128c2ecf20Sopenharmony_ci while ((mask2 <<= 1)) { 2138c2ecf20Sopenharmony_ci if (!(tmp & mask2)) 2148c2ecf20Sopenharmony_ci break; 2158c2ecf20Sopenharmony_ci AFFS_I(inode)->i_pa_cnt++; 2168c2ecf20Sopenharmony_ci mask |= mask2; 2178c2ecf20Sopenharmony_ci } 2188c2ecf20Sopenharmony_ci bm->bm_free -= AFFS_I(inode)->i_pa_cnt + 1; 2198c2ecf20Sopenharmony_ci 2208c2ecf20Sopenharmony_ci *data = cpu_to_be32(tmp & ~mask); 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_ci /* fix checksum */ 2238c2ecf20Sopenharmony_ci tmp = be32_to_cpu(*(__be32 *)bh->b_data); 2248c2ecf20Sopenharmony_ci *(__be32 *)bh->b_data = cpu_to_be32(tmp + mask); 2258c2ecf20Sopenharmony_ci 2268c2ecf20Sopenharmony_ci mark_buffer_dirty(bh); 2278c2ecf20Sopenharmony_ci affs_mark_sb_dirty(sb); 2288c2ecf20Sopenharmony_ci 2298c2ecf20Sopenharmony_ci mutex_unlock(&sbi->s_bmlock); 2308c2ecf20Sopenharmony_ci 2318c2ecf20Sopenharmony_ci pr_debug("%d\n", blk); 2328c2ecf20Sopenharmony_ci return blk; 2338c2ecf20Sopenharmony_ci 2348c2ecf20Sopenharmony_cierr_bh_read: 2358c2ecf20Sopenharmony_ci affs_error(sb,"affs_read_block","Cannot read bitmap block %u", bm->bm_key); 2368c2ecf20Sopenharmony_ci sbi->s_bmap_bh = NULL; 2378c2ecf20Sopenharmony_ci sbi->s_last_bmap = ~0; 2388c2ecf20Sopenharmony_cierr_full: 2398c2ecf20Sopenharmony_ci mutex_unlock(&sbi->s_bmlock); 2408c2ecf20Sopenharmony_ci pr_debug("failed\n"); 2418c2ecf20Sopenharmony_ci return 0; 2428c2ecf20Sopenharmony_ci} 2438c2ecf20Sopenharmony_ci 2448c2ecf20Sopenharmony_ciint affs_init_bitmap(struct super_block *sb, int *flags) 2458c2ecf20Sopenharmony_ci{ 2468c2ecf20Sopenharmony_ci struct affs_bm_info *bm; 2478c2ecf20Sopenharmony_ci struct buffer_head *bmap_bh = NULL, *bh = NULL; 2488c2ecf20Sopenharmony_ci __be32 *bmap_blk; 2498c2ecf20Sopenharmony_ci u32 size, blk, end, offset, mask; 2508c2ecf20Sopenharmony_ci int i, res = 0; 2518c2ecf20Sopenharmony_ci struct affs_sb_info *sbi = AFFS_SB(sb); 2528c2ecf20Sopenharmony_ci 2538c2ecf20Sopenharmony_ci if (*flags & SB_RDONLY) 2548c2ecf20Sopenharmony_ci return 0; 2558c2ecf20Sopenharmony_ci 2568c2ecf20Sopenharmony_ci if (!AFFS_ROOT_TAIL(sb, sbi->s_root_bh)->bm_flag) { 2578c2ecf20Sopenharmony_ci pr_notice("Bitmap invalid - mounting %s read only\n", sb->s_id); 2588c2ecf20Sopenharmony_ci *flags |= SB_RDONLY; 2598c2ecf20Sopenharmony_ci return 0; 2608c2ecf20Sopenharmony_ci } 2618c2ecf20Sopenharmony_ci 2628c2ecf20Sopenharmony_ci sbi->s_last_bmap = ~0; 2638c2ecf20Sopenharmony_ci sbi->s_bmap_bh = NULL; 2648c2ecf20Sopenharmony_ci sbi->s_bmap_bits = sb->s_blocksize * 8 - 32; 2658c2ecf20Sopenharmony_ci sbi->s_bmap_count = (sbi->s_partition_size - sbi->s_reserved + 2668c2ecf20Sopenharmony_ci sbi->s_bmap_bits - 1) / sbi->s_bmap_bits; 2678c2ecf20Sopenharmony_ci size = sbi->s_bmap_count * sizeof(*bm); 2688c2ecf20Sopenharmony_ci bm = sbi->s_bitmap = kzalloc(size, GFP_KERNEL); 2698c2ecf20Sopenharmony_ci if (!sbi->s_bitmap) { 2708c2ecf20Sopenharmony_ci pr_err("Bitmap allocation failed\n"); 2718c2ecf20Sopenharmony_ci return -ENOMEM; 2728c2ecf20Sopenharmony_ci } 2738c2ecf20Sopenharmony_ci 2748c2ecf20Sopenharmony_ci bmap_blk = (__be32 *)sbi->s_root_bh->b_data; 2758c2ecf20Sopenharmony_ci blk = sb->s_blocksize / 4 - 49; 2768c2ecf20Sopenharmony_ci end = blk + 25; 2778c2ecf20Sopenharmony_ci 2788c2ecf20Sopenharmony_ci for (i = sbi->s_bmap_count; i > 0; bm++, i--) { 2798c2ecf20Sopenharmony_ci affs_brelse(bh); 2808c2ecf20Sopenharmony_ci 2818c2ecf20Sopenharmony_ci bm->bm_key = be32_to_cpu(bmap_blk[blk]); 2828c2ecf20Sopenharmony_ci bh = affs_bread(sb, bm->bm_key); 2838c2ecf20Sopenharmony_ci if (!bh) { 2848c2ecf20Sopenharmony_ci pr_err("Cannot read bitmap\n"); 2858c2ecf20Sopenharmony_ci res = -EIO; 2868c2ecf20Sopenharmony_ci goto out; 2878c2ecf20Sopenharmony_ci } 2888c2ecf20Sopenharmony_ci if (affs_checksum_block(sb, bh)) { 2898c2ecf20Sopenharmony_ci pr_warn("Bitmap %u invalid - mounting %s read only.\n", 2908c2ecf20Sopenharmony_ci bm->bm_key, sb->s_id); 2918c2ecf20Sopenharmony_ci *flags |= SB_RDONLY; 2928c2ecf20Sopenharmony_ci goto out; 2938c2ecf20Sopenharmony_ci } 2948c2ecf20Sopenharmony_ci pr_debug("read bitmap block %d: %d\n", blk, bm->bm_key); 2958c2ecf20Sopenharmony_ci bm->bm_free = memweight(bh->b_data + 4, sb->s_blocksize - 4); 2968c2ecf20Sopenharmony_ci 2978c2ecf20Sopenharmony_ci /* Don't try read the extension if this is the last block, 2988c2ecf20Sopenharmony_ci * but we also need the right bm pointer below 2998c2ecf20Sopenharmony_ci */ 3008c2ecf20Sopenharmony_ci if (++blk < end || i == 1) 3018c2ecf20Sopenharmony_ci continue; 3028c2ecf20Sopenharmony_ci if (bmap_bh) 3038c2ecf20Sopenharmony_ci affs_brelse(bmap_bh); 3048c2ecf20Sopenharmony_ci bmap_bh = affs_bread(sb, be32_to_cpu(bmap_blk[blk])); 3058c2ecf20Sopenharmony_ci if (!bmap_bh) { 3068c2ecf20Sopenharmony_ci pr_err("Cannot read bitmap extension\n"); 3078c2ecf20Sopenharmony_ci res = -EIO; 3088c2ecf20Sopenharmony_ci goto out; 3098c2ecf20Sopenharmony_ci } 3108c2ecf20Sopenharmony_ci bmap_blk = (__be32 *)bmap_bh->b_data; 3118c2ecf20Sopenharmony_ci blk = 0; 3128c2ecf20Sopenharmony_ci end = sb->s_blocksize / 4 - 1; 3138c2ecf20Sopenharmony_ci } 3148c2ecf20Sopenharmony_ci 3158c2ecf20Sopenharmony_ci offset = (sbi->s_partition_size - sbi->s_reserved) % sbi->s_bmap_bits; 3168c2ecf20Sopenharmony_ci mask = ~(0xFFFFFFFFU << (offset & 31)); 3178c2ecf20Sopenharmony_ci pr_debug("last word: %d %d %d\n", offset, offset / 32 + 1, mask); 3188c2ecf20Sopenharmony_ci offset = offset / 32 + 1; 3198c2ecf20Sopenharmony_ci 3208c2ecf20Sopenharmony_ci if (mask) { 3218c2ecf20Sopenharmony_ci u32 old, new; 3228c2ecf20Sopenharmony_ci 3238c2ecf20Sopenharmony_ci /* Mark unused bits in the last word as allocated */ 3248c2ecf20Sopenharmony_ci old = be32_to_cpu(((__be32 *)bh->b_data)[offset]); 3258c2ecf20Sopenharmony_ci new = old & mask; 3268c2ecf20Sopenharmony_ci //if (old != new) { 3278c2ecf20Sopenharmony_ci ((__be32 *)bh->b_data)[offset] = cpu_to_be32(new); 3288c2ecf20Sopenharmony_ci /* fix checksum */ 3298c2ecf20Sopenharmony_ci //new -= old; 3308c2ecf20Sopenharmony_ci //old = be32_to_cpu(*(__be32 *)bh->b_data); 3318c2ecf20Sopenharmony_ci //*(__be32 *)bh->b_data = cpu_to_be32(old - new); 3328c2ecf20Sopenharmony_ci //mark_buffer_dirty(bh); 3338c2ecf20Sopenharmony_ci //} 3348c2ecf20Sopenharmony_ci /* correct offset for the bitmap count below */ 3358c2ecf20Sopenharmony_ci //offset++; 3368c2ecf20Sopenharmony_ci } 3378c2ecf20Sopenharmony_ci while (++offset < sb->s_blocksize / 4) 3388c2ecf20Sopenharmony_ci ((__be32 *)bh->b_data)[offset] = 0; 3398c2ecf20Sopenharmony_ci ((__be32 *)bh->b_data)[0] = 0; 3408c2ecf20Sopenharmony_ci ((__be32 *)bh->b_data)[0] = cpu_to_be32(-affs_checksum_block(sb, bh)); 3418c2ecf20Sopenharmony_ci mark_buffer_dirty(bh); 3428c2ecf20Sopenharmony_ci 3438c2ecf20Sopenharmony_ci /* recalculate bitmap count for last block */ 3448c2ecf20Sopenharmony_ci bm--; 3458c2ecf20Sopenharmony_ci bm->bm_free = memweight(bh->b_data + 4, sb->s_blocksize - 4); 3468c2ecf20Sopenharmony_ci 3478c2ecf20Sopenharmony_ciout: 3488c2ecf20Sopenharmony_ci affs_brelse(bh); 3498c2ecf20Sopenharmony_ci affs_brelse(bmap_bh); 3508c2ecf20Sopenharmony_ci return res; 3518c2ecf20Sopenharmony_ci} 3528c2ecf20Sopenharmony_ci 3538c2ecf20Sopenharmony_civoid affs_free_bitmap(struct super_block *sb) 3548c2ecf20Sopenharmony_ci{ 3558c2ecf20Sopenharmony_ci struct affs_sb_info *sbi = AFFS_SB(sb); 3568c2ecf20Sopenharmony_ci 3578c2ecf20Sopenharmony_ci if (!sbi->s_bitmap) 3588c2ecf20Sopenharmony_ci return; 3598c2ecf20Sopenharmony_ci 3608c2ecf20Sopenharmony_ci affs_brelse(sbi->s_bmap_bh); 3618c2ecf20Sopenharmony_ci sbi->s_bmap_bh = NULL; 3628c2ecf20Sopenharmony_ci sbi->s_last_bmap = ~0; 3638c2ecf20Sopenharmony_ci kfree(sbi->s_bitmap); 3648c2ecf20Sopenharmony_ci sbi->s_bitmap = NULL; 3658c2ecf20Sopenharmony_ci} 366