fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / fs / ext2 / balloc.c
index 7b776af..79a7c63 100644 (file)
@@ -6,18 +6,18 @@
  * Laboratoire MASI - Institut Blaise Pascal
  * Universite Pierre et Marie Curie (Paris VI)
  *
- *  Enhanced block allocation by Stephen Tweedie (sct@dcs.ed.ac.uk), 1993
+ *  Enhanced block allocation by Stephen Tweedie (sct@redhat.com), 1993
  *  Big-endian to little-endian byte-swapping/bitmaps by
  *        David S. Miller (davem@caip.rutgers.edu), 1995
  */
 
-#include <linux/config.h>
 #include "ext2.h"
 #include <linux/quotaops.h>
 #include <linux/sched.h>
 #include <linux/buffer_head.h>
-#include <linux/vs_base.h>
+#include <linux/capability.h>
 #include <linux/vs_dlimit.h>
+#include <linux/vs_tag.h>
 
 /*
  * balloc.c contains the blocks allocation and deallocation routines
@@ -54,9 +54,9 @@ struct ext2_group_desc * ext2_get_group_desc(struct super_block * sb,
 
                return NULL;
        }
-       
-       group_desc = block_group / EXT2_DESC_PER_BLOCK(sb);
-       offset = block_group % EXT2_DESC_PER_BLOCK(sb);
+
+       group_desc = block_group >> EXT2_DESC_PER_BLOCK_BITS(sb);
+       offset = block_group & (EXT2_DESC_PER_BLOCK(sb) - 1);
        if (!sbi->s_group_desc[group_desc]) {
                ext2_error (sb, "ext2_get_group_desc",
                            "Group descriptor not loaded - "
@@ -64,7 +64,7 @@ struct ext2_group_desc * ext2_get_group_desc(struct super_block * sb,
                             block_group, group_desc, offset);
                return NULL;
        }
-       
+
        desc = (struct ext2_group_desc *) sbi->s_group_desc[group_desc]->b_data;
        if (bh)
                *bh = sbi->s_group_desc[group_desc];
@@ -90,8 +90,8 @@ read_block_bitmap(struct super_block *sb, unsigned int block_group)
        if (!bh)
                ext2_error (sb, "read_block_bitmap",
                            "Cannot read block bitmap - "
-                           "block_group = %d, block_bitmap = %lu",
-                           block_group, (unsigned long) desc->bg_block_bitmap);
+                           "block_group = %d, block_bitmap = %u",
+                           block_group, le32_to_cpu(desc->bg_block_bitmap));
 error_out:
        return bh;
 }
@@ -104,13 +104,12 @@ static int reserve_blocks(struct super_block *sb, int count)
 {
        struct ext2_sb_info *sbi = EXT2_SB(sb);
        struct ext2_super_block *es = sbi->s_es;
-       unsigned free_blocks;
-       unsigned root_blocks;
+       unsigned long long free_blocks, root_blocks;
 
        free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
        root_blocks = le32_to_cpu(es->s_r_blocks_count);
 
-       DLIMIT_ADJUST_BLOCK(sb, vx_current_xid(), &free_blocks, &root_blocks);
+       DLIMIT_ADJUST_BLOCK(sb, dx_current_tag(), &free_blocks, &root_blocks);
 
        if (free_blocks < count)
                count = free_blocks;
@@ -240,12 +239,12 @@ do_more:
 
        for (i = 0, group_freed = 0; i < count; i++) {
                if (!ext2_clear_bit_atomic(sb_bgl_lock(sbi, block_group),
-                                       bit + i, (void *) bitmap_bh->b_data))
-                       ext2_error (sb, "ext2_free_blocks",
-                                     "bit already cleared for block %lu",
-                                     block + i);
-               else
+                                               bit + i, bitmap_bh->b_data)) {
+                       ext2_error(sb, __FUNCTION__,
+                               "bit already cleared for block %lu", block + i);
+               } else {
                        group_freed++;
+               }
        }
 
        mark_buffer_dirty(bitmap_bh);
@@ -262,7 +261,7 @@ do_more:
        }
 error_return:
        brelse(bitmap_bh);
-       DLIMIT_FREE_BLOCK(sb, inode->i_xid, freed);
+       DLIMIT_FREE_BLOCK(inode, freed);
        release_blocks(sb, freed);
        DQUOT_FREE_BLOCK(inode, freed);
 }
@@ -366,7 +365,7 @@ int ext2_new_block(struct inode *inode, unsigned long goal,
                *err = -ENOSPC;
                goto out_dquot;
        }
-       if (DLIMIT_ALLOC_BLOCK(sb, inode->i_xid, es_alloc)) {
+       if (DLIMIT_ALLOC_BLOCK(inode, es_alloc)) {
                *err = -ENOSPC;
                goto out_dlimit;
        }
@@ -517,7 +516,7 @@ got_block:
        *err = 0;
 out_release:
        group_release_blocks(sb, group_no, desc, gdp_bh, group_alloc);
-       DLIMIT_FREE_BLOCK(sb, inode->i_xid, es_alloc);
+       DLIMIT_FREE_BLOCK(inode, es_alloc);
 out_dlimit:
        release_blocks(sb, es_alloc);
 out_dquot:
@@ -531,6 +530,25 @@ io_error:
        goto out_release;
 }
 
+#ifdef EXT2FS_DEBUG
+
+static int nibblemap[] = {4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0};
+
+unsigned long ext2_count_free (struct buffer_head * map, unsigned int numchars)
+{
+       unsigned int i;
+       unsigned long sum = 0;
+
+       if (!map)
+               return (0);
+       for (i = 0; i < numchars; i++)
+               sum += nibblemap[map->b_data[i] & 0xf] +
+                       nibblemap[(map->b_data[i] >> 4) & 0xf];
+       return (sum);
+}
+
+#endif  /*  EXT2FS_DEBUG  */
+
 unsigned long ext2_count_free_blocks (struct super_block * sb)
 {
        struct ext2_group_desc * desc;
@@ -540,7 +558,6 @@ unsigned long ext2_count_free_blocks (struct super_block * sb)
        unsigned long bitmap_count, x;
        struct ext2_super_block *es;
 
-       lock_super (sb);
        es = EXT2_SB(sb)->s_es;
        desc_count = 0;
        bitmap_count = 0;
@@ -564,7 +581,6 @@ unsigned long ext2_count_free_blocks (struct super_block * sb)
        printk("ext2_count_free_blocks: stored = %lu, computed = %lu, %lu\n",
                (long)le32_to_cpu(es->s_free_blocks_count),
                desc_count, bitmap_count);
-       unlock_super (sb);
        return bitmap_count;
 #else
         for (i = 0; i < EXT2_SB(sb)->s_groups_count; i++) {
@@ -580,25 +596,24 @@ unsigned long ext2_count_free_blocks (struct super_block * sb)
 static inline int
 block_in_use(unsigned long block, struct super_block *sb, unsigned char *map)
 {
-       return ext2_test_bit ((block - le32_to_cpu(EXT2_SB(sb)->s_es->s_first_data_block)) %
+       return ext2_test_bit ((block -
+               le32_to_cpu(EXT2_SB(sb)->s_es->s_first_data_block)) %
                         EXT2_BLOCKS_PER_GROUP(sb), map);
 }
 
 static inline int test_root(int a, int b)
 {
-       if (a == 0)
-               return 1;
-       while (1) {
-               if (a == 1)
-                       return 1;
-               if (a % b)
-                       return 0;
-               a = a / b;
-       }
+       int num = b;
+
+       while (a > num)
+               num *= b;
+       return num == a;
 }
 
 static int ext2_group_sparse(int group)
 {
+       if (group <= 1)
+               return 1;
        return (test_root(group, 3) || test_root(group, 5) ||
                test_root(group, 7));
 }
@@ -636,76 +651,3 @@ unsigned long ext2_bg_num_gdb(struct super_block *sb, int group)
        return EXT2_SB(sb)->s_gdb_count;
 }
 
-#ifdef CONFIG_EXT2_CHECK
-/* Called at mount-time, super-block is locked */
-void ext2_check_blocks_bitmap (struct super_block * sb)
-{
-       struct buffer_head *bitmap_bh = NULL;
-       struct ext2_super_block * es;
-       unsigned long desc_count, bitmap_count, x, j;
-       unsigned long desc_blocks;
-       struct ext2_group_desc * desc;
-       int i;
-
-       es = EXT2_SB(sb)->s_es;
-       desc_count = 0;
-       bitmap_count = 0;
-       desc = NULL;
-       for (i = 0; i < EXT2_SB(sb)->s_groups_count; i++) {
-               desc = ext2_get_group_desc (sb, i, NULL);
-               if (!desc)
-                       continue;
-               desc_count += le16_to_cpu(desc->bg_free_blocks_count);
-               brelse(bitmap_bh);
-               bitmap_bh = read_block_bitmap(sb, i);
-               if (!bitmap_bh)
-                       continue;
-
-               if (ext2_bg_has_super(sb, i) &&
-                               !ext2_test_bit(0, bitmap_bh->b_data))
-                       ext2_error(sb, __FUNCTION__,
-                                  "Superblock in group %d is marked free", i);
-
-               desc_blocks = ext2_bg_num_gdb(sb, i);
-               for (j = 0; j < desc_blocks; j++)
-                       if (!ext2_test_bit(j + 1, bitmap_bh->b_data))
-                               ext2_error(sb, __FUNCTION__,
-                                          "Descriptor block #%ld in group "
-                                          "%d is marked free", j, i);
-
-               if (!block_in_use(le32_to_cpu(desc->bg_block_bitmap),
-                                       sb, bitmap_bh->b_data))
-                       ext2_error(sb, "ext2_check_blocks_bitmap",
-                                   "Block bitmap for group %d is marked free",
-                                   i);
-
-               if (!block_in_use(le32_to_cpu(desc->bg_inode_bitmap),
-                                       sb, bitmap_bh->b_data))
-                       ext2_error(sb, "ext2_check_blocks_bitmap",
-                                   "Inode bitmap for group %d is marked free",
-                                   i);
-
-               for (j = 0; j < EXT2_SB(sb)->s_itb_per_group; j++)
-                       if (!block_in_use(le32_to_cpu(desc->bg_inode_table) + j,
-                                               sb, bitmap_bh->b_data))
-                               ext2_error (sb, "ext2_check_blocks_bitmap",
-                                           "Block #%ld of the inode table in "
-                                           "group %d is marked free", j, i);
-
-               x = ext2_count_free(bitmap_bh, sb->s_blocksize);
-               if (le16_to_cpu(desc->bg_free_blocks_count) != x)
-                       ext2_error (sb, "ext2_check_blocks_bitmap",
-                                   "Wrong free blocks count for group %d, "
-                                   "stored = %d, counted = %lu", i,
-                                   le16_to_cpu(desc->bg_free_blocks_count), x);
-               bitmap_count += x;
-       }
-       if (le32_to_cpu(es->s_free_blocks_count) != bitmap_count)
-               ext2_error (sb, "ext2_check_blocks_bitmap",
-                       "Wrong free blocks count in super block, "
-                       "stored = %lu, counted = %lu",
-                       (unsigned long)le32_to_cpu(es->s_free_blocks_count),
-                       bitmap_count);
-       brelse(bitmap_bh);
-}
-#endif