root/fs/ext2/balloc.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. find_first_zero_bit
  2. find_next_zero_bit
  3. find_first_zero_byte
  4. get_group_desc
  5. read_block_bitmap
  6. load__block_bitmap
  7. load_block_bitmap
  8. ext2_free_blocks
  9. ext2_new_block
  10. ext2_count_free_blocks
  11. block_in_use
  12. ext2_check_blocks_bitmap

   1 /*
   2  *  linux/fs/ext2/balloc.c
   3  *
   4  *  Copyright (C) 1992, 1993, 1994  Remy Card (card@masi.ibp.fr)
   5  *                                  Laboratoire MASI - Institut Blaise Pascal
   6  *                                  Universite Pierre et Marie Curie (Paris VI)
   7  *
   8  *  Enhanced block allocation by Stephen Tweedie (sct@dcs.ed.ac.uk), 1993
   9  */
  10 
  11 /*
  12  * balloc.c contains the blocks allocation and deallocation routines
  13  */
  14 
  15 /*
  16  * The free blocks are managed by bitmaps.  A file system contains several
  17  * blocks groups.  Each group contains 1 bitmap block for blocks, 1 bitmap
  18  * block for inodes, N blocks for the inode table and data blocks.
  19  *
  20  * The file system contains group descriptors which are located after the
  21  * super block.  Each descriptor contains the number of the bitmap block and
  22  * the free blocks count in the block.  The descriptors are loaded in memory
  23  * when a file system is mounted (see ext2_read_super).
  24  */
  25 
  26 #include <linux/fs.h>
  27 #include <linux/ext2_fs.h>
  28 #include <linux/stat.h>
  29 #include <linux/sched.h>
  30 #include <linux/string.h>
  31 #include <linux/locks.h>
  32 
  33 #include <asm/bitops.h>
  34 
  35 #define clear_block(addr,size) \
  36         __asm__("cld\n\t" \
  37                 "rep\n\t" \
  38                 "stosl" \
  39                 : \
  40                 :"a" (0), "c" (size / 4), "D" ((long) (addr)) \
  41                 :"cx", "di")
  42 
  43 #define in_range(b, first, len)         ((b) >= (first) && (b) <= (first) + (len) - 1)
  44 
  45 static inline int find_first_zero_bit (unsigned long * addr, unsigned size)
     /* [previous][next][first][last][top][bottom][index][help] */
  46 {
  47         int res;
  48 
  49         if (!size)
  50                 return 0;
  51         __asm__("
  52                 cld
  53                 movl $-1,%%eax
  54                 repe; scasl
  55                 je 1f
  56                 subl $4,%%edi
  57                 movl (%%edi),%%eax
  58                 notl %%eax
  59                 bsfl %%eax,%%edx
  60                 jmp 2f
  61 1:              xorl %%edx,%%edx
  62 2:              subl %%ebx,%%edi
  63                 shll $3,%%edi
  64                 addl %%edi,%%edx"
  65                 :"=d" (res)
  66                 :"c" ((size + 31) >> 5), "D" (addr), "b" (addr)
  67                 :"ax", "bx", "cx", "di");
  68         return res;
  69 }
  70 
  71 static inline int find_next_zero_bit (unsigned long * addr, int size,
     /* [previous][next][first][last][top][bottom][index][help] */
  72                                       int offset)
  73 {
  74         unsigned long * p = ((unsigned long *) addr) + (offset >> 5);
  75         int set = 0, bit = offset & 31, res;
  76         
  77         if (bit) {
  78                 /*
  79                  * Look for zero in first byte
  80                  */
  81                 __asm__("
  82                         bsfl %1,%0
  83                         jne 1f
  84                         movl $32, %0
  85 1:                      "
  86                         : "=r" (set)
  87                         : "r" (~(*p >> bit)));
  88                 if (set < (32 - bit))
  89                         return set + offset;
  90                 set = 32 - bit;
  91                 p++;
  92         }
  93         /*
  94          * No zero yet, search remaining full bytes for a zero
  95          */
  96         res = find_first_zero_bit (p, size - 32 * (p - addr));
  97         return (offset + set + res);
  98 }
  99 
 100 static inline char * find_first_zero_byte (char * addr, int size)
     /* [previous][next][first][last][top][bottom][index][help] */
 101 {
 102         char *res;
 103 
 104         if (!size)
 105                 return 0;
 106         __asm__("
 107                 cld
 108                 mov $0,%%eax
 109                 repnz; scasb
 110                 jnz 1f
 111                 dec %%edi
 112 1:              "
 113                 : "=D" (res)
 114                 : "0" (addr), "c" (size)
 115                 : "ax");
 116         return res;
 117 }
 118 
 119 static struct ext2_group_desc * get_group_desc (struct super_block * sb,
     /* [previous][next][first][last][top][bottom][index][help] */
 120                                                 unsigned int block_group,
 121                                                 struct buffer_head ** bh)
 122 {
 123         unsigned long group_desc;
 124         unsigned long desc;
 125         struct ext2_group_desc * gdp;
 126 
 127         if (block_group >= sb->u.ext2_sb.s_groups_count)
 128                 ext2_panic (sb, "get_group_desc",
 129                             "block_group >= groups_count\n"
 130                             "block_group = %d, groups_count = %lu",
 131                             block_group, sb->u.ext2_sb.s_groups_count);
 132 
 133         group_desc = block_group / EXT2_DESC_PER_BLOCK(sb);
 134         desc = block_group % EXT2_DESC_PER_BLOCK(sb);
 135         if (!sb->u.ext2_sb.s_group_desc[group_desc])
 136                 ext2_panic (sb, "get_group_desc",
 137                             "Group descriptor not loaded\n"
 138                             "block_group = %d, group_desc = %lu, desc = %lu",
 139                              block_group, group_desc, desc);
 140         gdp = (struct ext2_group_desc *) 
 141               sb->u.ext2_sb.s_group_desc[group_desc]->b_data;
 142         if (bh)
 143                 *bh = sb->u.ext2_sb.s_group_desc[group_desc];
 144         return gdp + desc;
 145 }
 146 
 147 static void read_block_bitmap (struct super_block * sb,
     /* [previous][next][first][last][top][bottom][index][help] */
 148                                unsigned int block_group,
 149                                unsigned long bitmap_nr)
 150 {
 151         struct ext2_group_desc * gdp;
 152         struct buffer_head * bh;
 153         
 154         gdp = get_group_desc (sb, block_group, NULL);
 155         bh = bread (sb->s_dev, gdp->bg_block_bitmap, sb->s_blocksize);
 156         if (!bh)
 157                 ext2_panic (sb, "read_block_bitmap",
 158                             "Cannot read block bitmap\n"
 159                             "block_group = %d, block_bitmap = %lu",
 160                             block_group, gdp->bg_block_bitmap);
 161         sb->u.ext2_sb.s_block_bitmap_number[bitmap_nr] = block_group;
 162         sb->u.ext2_sb.s_block_bitmap[bitmap_nr] = bh;
 163 }
 164 
 165 /*
 166  * load_block_bitmap loads the block bitmap for a blocks group
 167  *
 168  * It maintains a cache for the last bitmaps loaded.  This cache is managed
 169  * with a LRU algorithm.
 170  *
 171  * Notes:
 172  * 1/ There is one cache per mounted file system.
 173  * 2/ If the file system contains less than EXT2_MAX_GROUP_LOADED groups,
 174  *    this function reads the bitmap without maintaining a LRU cache.
 175  */
 176 static int load__block_bitmap (struct super_block * sb,
     /* [previous][next][first][last][top][bottom][index][help] */
 177                                unsigned int block_group)
 178 {
 179         int i, j;
 180         unsigned long block_bitmap_number;
 181         struct buffer_head * block_bitmap;
 182 
 183         if (block_group >= sb->u.ext2_sb.s_groups_count)
 184                 ext2_panic (sb, "load_block_bitmap",
 185                             "block_group >= groups_count\n"
 186                             "block_group = %d, groups_count = %lu",
 187                             block_group, sb->u.ext2_sb.s_groups_count);
 188 
 189         if (sb->u.ext2_sb.s_groups_count <= EXT2_MAX_GROUP_LOADED) {
 190                 if (sb->u.ext2_sb.s_block_bitmap[block_group]) {
 191                         if (sb->u.ext2_sb.s_block_bitmap_number[block_group] !=
 192                             block_group)
 193                                 ext2_panic (sb, "load_block_bitmap",
 194                                             "block_group != block_bitmap_number");
 195                         else
 196                                 return block_group;
 197                 } else {
 198                         read_block_bitmap (sb, block_group, block_group);
 199                         return block_group;
 200                 }
 201         }
 202 
 203         for (i = 0; i < sb->u.ext2_sb.s_loaded_block_bitmaps &&
 204                     sb->u.ext2_sb.s_block_bitmap_number[i] != block_group; i++)
 205                 ;
 206         if (i < sb->u.ext2_sb.s_loaded_block_bitmaps &&
 207             sb->u.ext2_sb.s_block_bitmap_number[i] == block_group) {
 208                 block_bitmap_number = sb->u.ext2_sb.s_block_bitmap_number[i];
 209                 block_bitmap = sb->u.ext2_sb.s_block_bitmap[i];
 210                 for (j = i; j > 0; j--) {
 211                         sb->u.ext2_sb.s_block_bitmap_number[j] =
 212                                 sb->u.ext2_sb.s_block_bitmap_number[j - 1];
 213                         sb->u.ext2_sb.s_block_bitmap[j] =
 214                                 sb->u.ext2_sb.s_block_bitmap[j - 1];
 215                 }
 216                 sb->u.ext2_sb.s_block_bitmap_number[0] = block_bitmap_number;
 217                 sb->u.ext2_sb.s_block_bitmap[0] = block_bitmap;
 218         } else {
 219                 if (sb->u.ext2_sb.s_loaded_block_bitmaps < EXT2_MAX_GROUP_LOADED)
 220                         sb->u.ext2_sb.s_loaded_block_bitmaps++;
 221                 else
 222                         brelse (sb->u.ext2_sb.s_block_bitmap[EXT2_MAX_GROUP_LOADED - 1]);
 223                 for (j = sb->u.ext2_sb.s_loaded_block_bitmaps - 1; j > 0;  j--) {
 224                         sb->u.ext2_sb.s_block_bitmap_number[j] =
 225                                 sb->u.ext2_sb.s_block_bitmap_number[j - 1];
 226                         sb->u.ext2_sb.s_block_bitmap[j] =
 227                                 sb->u.ext2_sb.s_block_bitmap[j - 1];
 228                 }
 229                 read_block_bitmap (sb, block_group, 0);
 230         }
 231         return 0;
 232 }
 233 
 234 static inline int load_block_bitmap (struct super_block * sb,
     /* [previous][next][first][last][top][bottom][index][help] */
 235                                      unsigned int block_group)
 236 {
 237         if (sb->u.ext2_sb.s_loaded_block_bitmaps > 0 &&
 238             sb->u.ext2_sb.s_block_bitmap_number[0] == block_group)
 239                 return 0;
 240         
 241         if (sb->u.ext2_sb.s_groups_count <= EXT2_MAX_GROUP_LOADED && 
 242             sb->u.ext2_sb.s_block_bitmap_number[block_group] == block_group &&
 243             sb->u.ext2_sb.s_block_bitmap[block_group]) 
 244                 return block_group;
 245 
 246         return load__block_bitmap (sb, block_group);
 247 }
 248 
 249 void ext2_free_blocks (struct super_block * sb, unsigned long block,
     /* [previous][next][first][last][top][bottom][index][help] */
 250                        unsigned long count)
 251 {
 252         struct buffer_head * bh;
 253         struct buffer_head * bh2;
 254         unsigned long block_group;
 255         unsigned long bit;
 256         unsigned long i;
 257         int bitmap_nr;
 258         struct ext2_group_desc * gdp;
 259         struct ext2_super_block * es;
 260 
 261         if (!sb) {
 262                 printk ("ext2_free_blocks: nonexistent device");
 263                 return;
 264         }
 265         lock_super (sb);
 266         es = sb->u.ext2_sb.s_es;
 267         if (block < es->s_first_data_block || 
 268             (block + count) > es->s_blocks_count) {
 269                 ext2_error (sb, "ext2_free_blocks",
 270                             "Freeing blocks not in datazone\n"
 271                             "block = %lu, count = %lu", block, count);
 272                 unlock_super (sb);
 273                 return;
 274         }
 275 
 276         ext2_debug ("freeing block %lu\n", block);
 277 
 278         block_group = (block - es->s_first_data_block) /
 279                       EXT2_BLOCKS_PER_GROUP(sb);
 280         bit = (block - es->s_first_data_block) % EXT2_BLOCKS_PER_GROUP(sb);
 281         if (bit + count > EXT2_BLOCKS_PER_GROUP(sb))
 282                 ext2_panic (sb, "ext2_free_blocks",
 283                             "Freeing blocks across group boundary\n"
 284                             "Block = %lu, count = %lu",
 285                             block, count);
 286         bitmap_nr = load_block_bitmap (sb, block_group);
 287         bh = sb->u.ext2_sb.s_block_bitmap[bitmap_nr];
 288         gdp = get_group_desc (sb, block_group, &bh2);
 289 
 290         if (test_opt (sb, CHECK_STRICT) &&
 291             (in_range (gdp->bg_block_bitmap, block, count) ||
 292              in_range (gdp->bg_inode_bitmap, block, count) ||
 293              in_range (block, gdp->bg_inode_table,
 294                        sb->u.ext2_sb.s_itb_per_group) ||
 295              in_range (block + count - 1, gdp->bg_inode_table,
 296                        sb->u.ext2_sb.s_itb_per_group)))
 297                 ext2_panic (sb, "ext2_free_blocks",
 298                             "Freeing blocks in system zones\n"
 299                             "Block = %lu, count = %lu",
 300                             block, count);
 301 
 302         for (i = 0; i < count; i++) {
 303                 if (!clear_bit (bit + i, bh->b_data))
 304                         ext2_warning (sb, "ext2_free_blocks",
 305                                       "bit already cleared for block %lu", 
 306                                       block);
 307                 else {
 308                         gdp->bg_free_blocks_count++;
 309                         es->s_free_blocks_count++;
 310                 }
 311         }
 312         
 313         mark_buffer_dirty(bh2, 1);
 314         mark_buffer_dirty(sb->u.ext2_sb.s_sbh, 1);
 315 
 316         mark_buffer_dirty(bh, 1);
 317         if (sb->s_flags & MS_SYNC) {
 318                 ll_rw_block (WRITE, 1, &bh);
 319                 wait_on_buffer (bh);
 320         }
 321         sb->s_dirt = 1;
 322         unlock_super (sb);
 323         return;
 324 }
 325 
 326 /*
 327  * ext2_new_block uses a goal block to assist allocation.  If the goal is
 328  * free, or there is a free block within 32 blocks of the goal, that block
 329  * is allocated.  Otherwise a forward search is made for a free block; within 
 330  * each block group the search first looks for an entire free byte in the block
 331  * bitmap, and then for any free bit if that fails.
 332  */
 333 int ext2_new_block (struct super_block * sb, unsigned long goal,
     /* [previous][next][first][last][top][bottom][index][help] */
 334                     unsigned long * prealloc_count,
 335                     unsigned long * prealloc_block)
 336 {
 337         struct buffer_head * bh;
 338         struct buffer_head * bh2;
 339         char * p, * r;
 340         int i, j, k, tmp;
 341         unsigned long lmap;
 342         int bitmap_nr;
 343         struct ext2_group_desc * gdp;
 344         struct ext2_super_block * es;
 345 
 346 #ifdef EXT2FS_DEBUG
 347         static int goal_hits = 0, goal_attempts = 0;
 348 #endif
 349         if (!sb) {
 350                 printk ("ext2_new_block: nonexistent device");
 351                 return 0;
 352         }
 353         lock_super (sb);
 354         es = sb->u.ext2_sb.s_es;
 355         if (es->s_free_blocks_count <= es->s_r_blocks_count && !suser()) {
 356                 unlock_super (sb);
 357                 return 0;
 358         }
 359 
 360         ext2_debug ("goal=%lu.\n", goal);
 361 
 362 repeat:
 363         /*
 364          * First, test whether the goal block is free.
 365          */
 366         if (goal < es->s_first_data_block || goal >= es->s_blocks_count)
 367                 goal = es->s_first_data_block;
 368         i = (goal - es->s_first_data_block) / EXT2_BLOCKS_PER_GROUP(sb);
 369         gdp = get_group_desc (sb, i, &bh2);
 370         if (gdp->bg_free_blocks_count > 0) {
 371                 j = ((goal - es->s_first_data_block) % EXT2_BLOCKS_PER_GROUP(sb));
 372 #ifdef EXT2FS_DEBUG
 373                 if (j)
 374                         goal_attempts++;
 375 #endif
 376                 bitmap_nr = load_block_bitmap (sb, i);
 377                 bh = sb->u.ext2_sb.s_block_bitmap[bitmap_nr];
 378 
 379                 ext2_debug ("goal is at %d:%d.\n", i, j);
 380 
 381                 if (!test_bit(j, bh->b_data)) {
 382 #ifdef EXT2FS_DEBUG
 383                         goal_hits++;
 384                         ext2_debug ("goal bit allocated.\n");
 385 #endif
 386                         goto got_block;
 387                 }
 388                 if (j) {
 389                         /*
 390                          * The goal was occupied; search forward for a free 
 391                          * block within the next 32 blocks
 392                          */
 393                         lmap = ((((unsigned long *) bh->b_data)[j >> 5]) >>
 394                                 ((j & 31) + 1));
 395                         if (j < EXT2_BLOCKS_PER_GROUP(sb) - 32)
 396                                 lmap |= (((unsigned long *) bh->b_data)[(j >> 5) + 1]) <<
 397                                  (31 - (j & 31));
 398                         else
 399                                 lmap |= 0xffffffff << (31 - (j & 31));
 400                         if (lmap != 0xffffffffl) {
 401                                 __asm__ ("bsfl %1,%0"
 402                                          : "=r" (k)
 403                                          : "r" (~lmap));
 404                                 k++;
 405                                 if ((j + k) < EXT2_BLOCKS_PER_GROUP(sb)) {
 406                                         j += k;
 407                                         goto got_block;
 408                                 }
 409                         }
 410                 }
 411         
 412                 ext2_debug ("Bit not found near goal\n");
 413 
 414                 /*
 415                  * There has been no free block found in the near vicinity
 416                  * of the goal: do a search forward through the block groups,
 417                  * searching in each group first for an entire free byte in
 418                  * the bitmap and then for any free bit.
 419                  * 
 420                  * Search first in the remainder of the current group; then,
 421                  * cyclicly search throught the rest of the groups.
 422                  */
 423                 p = ((char *) bh->b_data) + (j >> 3);
 424                 r = find_first_zero_byte (p, 
 425                                           (EXT2_BLOCKS_PER_GROUP(sb) - j + 7) >> 3);
 426                 k = (r - ((char *) bh->b_data)) << 3;
 427                 if (k < EXT2_BLOCKS_PER_GROUP(sb)) {
 428                         j = k;
 429                         goto search_back;
 430                 }
 431                 k = find_next_zero_bit ((unsigned long *) bh->b_data, 
 432                                         EXT2_BLOCKS_PER_GROUP(sb),
 433                                         j);
 434                 if (k < EXT2_BLOCKS_PER_GROUP(sb)) {
 435                         j = k;
 436                         goto got_block;
 437                 }
 438         }
 439 
 440         ext2_debug ("Bit not found in block group %d.\n", i);
 441 
 442         /*
 443          * Now search the rest of the groups.  We assume that 
 444          * i and gdp correctly point to the last group visited.
 445          */
 446         for (k = 0; k < sb->u.ext2_sb.s_groups_count; k++) {
 447                 i++;
 448                 if (i >= sb->u.ext2_sb.s_groups_count)
 449                         i = 0;
 450                 gdp = get_group_desc (sb, i, &bh2);
 451                 if (gdp->bg_free_blocks_count > 0)
 452                         break;
 453         }
 454         if (k >= sb->u.ext2_sb.s_groups_count) {
 455                 unlock_super (sb);
 456                 return 0;
 457         }
 458         bitmap_nr = load_block_bitmap (sb, i);
 459         bh = sb->u.ext2_sb.s_block_bitmap[bitmap_nr];
 460         r = find_first_zero_byte (bh->b_data, 
 461                                   EXT2_BLOCKS_PER_GROUP(sb) >> 3);
 462         j = (r - bh->b_data) << 3;
 463         if (j < EXT2_BLOCKS_PER_GROUP(sb))
 464                 goto search_back;
 465         else
 466                 j = find_first_zero_bit ((unsigned long *) bh->b_data,
 467                                          EXT2_BLOCKS_PER_GROUP(sb));
 468         if (j >= EXT2_BLOCKS_PER_GROUP(sb)) {
 469                 ext2_error (sb, "ext2_new_block",
 470                             "Free blocks count corrupted for block group %d", i);
 471                 unlock_super (sb);
 472                 return 0;
 473         }
 474 
 475 search_back:
 476         /* 
 477          * We have succeeded in finding a free byte in the block
 478          * bitmap.  Now search backwards up to 7 bits to find the
 479          * start of this group of free blocks.
 480          */
 481         for (k = 0; k < 7 && j > 0 && !test_bit (j - 1, bh->b_data); k++, j--);
 482         
 483 got_block:
 484 
 485         ext2_debug ("using block group %d(%d)\n", i, gdp->bg_free_blocks_count);
 486 
 487         tmp = j + i * EXT2_BLOCKS_PER_GROUP(sb) + es->s_first_data_block;
 488 
 489         if (test_opt (sb, CHECK_STRICT) &&
 490             (tmp == gdp->bg_block_bitmap ||
 491              tmp == gdp->bg_inode_bitmap ||
 492              in_range (tmp, gdp->bg_inode_table, sb->u.ext2_sb.s_itb_per_group)))
 493                 ext2_panic (sb, "ext2_new_block",
 494                             "Allocating block in system zone\n"
 495                             "block = %u", tmp);
 496 
 497         if (set_bit (j, bh->b_data)) {
 498                 ext2_warning (sb, "ext2_new_block",
 499                               "bit already set for block %d", j);
 500                 goto repeat;
 501         }
 502 
 503         ext2_debug ("found bit %d\n", j);
 504 
 505         /*
 506          * Do block preallocation now if required.
 507          */
 508 #ifdef EXT2_PREALLOCATE
 509         if (prealloc_block) {
 510                 *prealloc_count = 0;
 511                 *prealloc_block = tmp + 1;
 512                 for (k = 1;
 513                      k < 8 && (j + k) < EXT2_BLOCKS_PER_GROUP(sb); k++) {
 514                         if (set_bit (j + k, bh->b_data))
 515                                 break;
 516                         (*prealloc_count)++;
 517                 }       
 518                 gdp->bg_free_blocks_count -= *prealloc_count;
 519                 es->s_free_blocks_count -= *prealloc_count;
 520                 ext2_debug ("Preallocated a further %lu bits.\n",
 521                             *prealloc_count);
 522         }
 523 #endif
 524 
 525         j = tmp;
 526 
 527         mark_buffer_dirty(bh, 1);
 528         if (sb->s_flags & MS_SYNC) {
 529                 ll_rw_block (WRITE, 1, &bh);
 530                 wait_on_buffer (bh);
 531         }
 532 
 533         if (j >= es->s_blocks_count) {
 534                 ext2_error (sb, "ext2_new_block",
 535                             "block >= blocks count\n"
 536                             "block_group = %d, block=%d", i, j);
 537                 unlock_super (sb);
 538                 return 0;
 539         }
 540         if (!(bh = getblk (sb->s_dev, j, sb->s_blocksize))) {
 541                 ext2_error (sb, "ext2_new_block", "cannot get block %d", j);
 542                 unlock_super (sb);
 543                 return 0;
 544         }
 545         clear_block (bh->b_data, sb->s_blocksize);
 546         bh->b_uptodate = 1;
 547         mark_buffer_dirty(bh, 1);
 548         brelse (bh);
 549 
 550         ext2_debug ("allocating block %d. "
 551                     "Goal hits %d of %d.\n", j, goal_hits, goal_attempts);
 552 
 553         gdp->bg_free_blocks_count--;
 554         mark_buffer_dirty(bh2, 1);
 555         es->s_free_blocks_count--;
 556         mark_buffer_dirty(sb->u.ext2_sb.s_sbh, 1);
 557         sb->s_dirt = 1;
 558         unlock_super (sb);
 559         return j;
 560 }
 561 
 562 unsigned long ext2_count_free_blocks (struct super_block * sb)
     /* [previous][next][first][last][top][bottom][index][help] */
 563 {
 564 #ifdef EXT2FS_DEBUG
 565         struct ext2_super_block * es;
 566         unsigned long desc_count, bitmap_count, x;
 567         int bitmap_nr;
 568         struct ext2_group_desc * gdp;
 569         int i;
 570         
 571         lock_super (sb);
 572         es = sb->u.ext2_sb.s_es;
 573         desc_count = 0;
 574         bitmap_count = 0;
 575         gdp = NULL;
 576         for (i = 0; i < sb->u.ext2_sb.s_groups_count; i++) {
 577                 gdp = get_group_desc (sb, i, NULL);
 578                 desc_count += gdp->bg_free_blocks_count;
 579                 bitmap_nr = load_block_bitmap (sb, i);
 580                 x = ext2_count_free (sb->u.ext2_sb.s_block_bitmap[bitmap_nr],
 581                                      sb->s_blocksize);
 582                 printk ("group %d: stored = %d, counted = %lu\n",
 583                         i, gdp->bg_free_blocks_count, x);
 584                 bitmap_count += x;
 585         }
 586         printk("ext2_count_free_blocks: stored = %lu, computed = %lu, %lu\n",
 587                es->s_free_blocks_count, desc_count, bitmap_count);
 588         unlock_super (sb);
 589         return bitmap_count;
 590 #else
 591         return sb->u.ext2_sb.s_es->s_free_blocks_count;
 592 #endif
 593 }
 594 
 595 static inline int block_in_use (unsigned long block,
     /* [previous][next][first][last][top][bottom][index][help] */
 596                                 struct super_block * sb,
 597                                 unsigned char * map)
 598 {
 599         return test_bit ((block - sb->u.ext2_sb.s_es->s_first_data_block) %
 600                          EXT2_BLOCKS_PER_GROUP(sb), map);
 601 }
 602 
 603 void ext2_check_blocks_bitmap (struct super_block * sb)
     /* [previous][next][first][last][top][bottom][index][help] */
 604 {
 605         struct buffer_head * bh;
 606         struct ext2_super_block * es;
 607         unsigned long desc_count, bitmap_count, x;
 608         unsigned long desc_blocks;
 609         int bitmap_nr;
 610         struct ext2_group_desc * gdp;
 611         int i, j;
 612 
 613         lock_super (sb);
 614         es = sb->u.ext2_sb.s_es;
 615         desc_count = 0;
 616         bitmap_count = 0;
 617         gdp = NULL;
 618         desc_blocks = (sb->u.ext2_sb.s_groups_count + EXT2_DESC_PER_BLOCK(sb) - 1) /
 619                       EXT2_DESC_PER_BLOCK(sb);
 620         for (i = 0; i < sb->u.ext2_sb.s_groups_count; i++) {
 621                 gdp = get_group_desc (sb, i, NULL);
 622                 desc_count += gdp->bg_free_blocks_count;
 623                 bitmap_nr = load_block_bitmap (sb, i);
 624                 bh = sb->u.ext2_sb.s_block_bitmap[bitmap_nr];
 625 
 626                 if (!test_bit (0, bh->b_data))
 627                         ext2_error (sb, "ext2_check_blocks_bitmap",
 628                                     "Superblock in group %d is marked free", i);
 629 
 630                 for (j = 0; j < desc_blocks; j++)
 631                         if (!test_bit (j + 1, bh->b_data))
 632                                 ext2_error (sb, "ext2_check_blocks_bitmap",
 633                                             "Descriptor block #%d in group "
 634                                             "%d is marked free", j, i);
 635 
 636                 if (!block_in_use (gdp->bg_block_bitmap, sb, bh->b_data))
 637                         ext2_error (sb, "ext2_check_blocks_bitmap",
 638                                     "Block bitmap for group %d is marked free",
 639                                     i);
 640 
 641                 if (!block_in_use (gdp->bg_inode_bitmap, sb, bh->b_data))
 642                         ext2_error (sb, "ext2_check_blocks_bitmap",
 643                                     "Inode bitmap for group %d is marked free",
 644                                     i);
 645 
 646                 for (j = 0; j < sb->u.ext2_sb.s_itb_per_group; j++)
 647                         if (!block_in_use (gdp->bg_inode_table + j, sb, bh->b_data))
 648                                 ext2_error (sb, "ext2_check_blocks_bitmap",
 649                                             "Block #%d of the inode table in "
 650                                             "group %d is marked free", j, i);
 651 
 652                 x = ext2_count_free (bh, sb->s_blocksize);
 653                 if (gdp->bg_free_blocks_count != x)
 654                         ext2_error (sb, "ext2_check_blocks_bitmap",
 655                                     "Wrong free blocks count for group %d, "
 656                                     "stored = %d, counted = %lu", i,
 657                                     gdp->bg_free_blocks_count, x);
 658                 bitmap_count += x;
 659         }
 660         if (es->s_free_blocks_count != bitmap_count)
 661                 ext2_error (sb, "ext2_check_blocks_bitmap",
 662                             "Wrong free blocks count in super block, "
 663                             "stored = %lu, counted = %lu",
 664                             es->s_free_blocks_count, bitmap_count);
 665         unlock_super (sb);
 666 }

/* [previous][next][first][last][top][bottom][index][help] */