root/fs/affs/bitmap.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. affs_count_free_blocks
  2. affs_free_block
  3. affs_alloc_block
  4. affs_init_bitmap
  5. affs_free_bitmap

   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 }

/* [<][>][^][v][top][bottom][index][help] */