A checksum of each group descriptor is used to ensure that corruption in
the group descriptor's bit flags does not cause incorrect operation.
-Index: linux-2.6.18.8.orig/include/linux/ext3_fs.h
+Index: linux-2.6.18-53.1.14/include/linux/ext3_fs.h
===================================================================
---- linux-2.6.18.8.orig.orig/include/linux/ext3_fs.h 2007-07-02 11:09:25.000000000 +0200
-+++ linux-2.6.18.8.orig/include/linux/ext3_fs.h 2007-07-02 11:09:31.000000000 +0200
+--- linux-2.6.18-53.1.14.orig/include/linux/ext3_fs.h
++++ linux-2.6.18-53.1.14/include/linux/ext3_fs.h
@@ -150,16 +150,22 @@ struct ext3_allocation_request {
*/
struct ext3_group_desc
EXT4_FEATURE_RO_COMPAT_DIR_NLINK| \
EXT3_FEATURE_RO_COMPAT_BTREE_DIR)
-Index: linux-2.6.18.8.orig/fs/ext3/resize.c
+Index: linux-2.6.18-53.1.14/fs/ext3/resize.c
===================================================================
---- linux-2.6.18.8.orig.orig/fs/ext3/resize.c 2007-06-21 14:53:15.000000000 +0200
-+++ linux-2.6.18.8.orig/fs/ext3/resize.c 2007-07-02 11:09:26.000000000 +0200
+--- linux-2.6.18-53.1.14.orig/fs/ext3/resize.c
++++ linux-2.6.18-53.1.14/fs/ext3/resize.c
@@ -18,6 +18,7 @@
#include <linux/errno.h>
#include <linux/slab.h>
#define outside(b, first, last) ((b) < (first) || (b) >= (last))
#define inside(b, first, last) ((b) >= (first) && (b) < (last))
-@@ -822,6 +823,7 @@ int ext3_group_add(struct super_block *s
+@@ -137,25 +138,6 @@ static struct buffer_head *bclean(handle
+ }
+
+ /*
+- * To avoid calling the atomic setbit hundreds or thousands of times, we only
+- * need to use it within a single byte (to ensure we get endianness right).
+- * We can use memset for the rest of the bitmap as there are no other users.
+- */
+-static void mark_bitmap_end(int start_bit, int end_bit, char *bitmap)
+-{
+- int i;
+-
+- if (start_bit >= end_bit)
+- return;
+-
+- ext3_debug("mark end bits +%d through +%d used\n", start_bit, end_bit);
+- for (i = start_bit; i < ((start_bit + 7) & ~7UL); i++)
+- ext3_set_bit(i, bitmap);
+- if (i < end_bit)
+- memset(bitmap + (i >> 3), 0xff, (end_bit - i) >> 3);
+-}
+-
+-/*
+ * If we have fewer than thresh credits, extend by EXT3_MAX_TRANS_DATA.
+ * If that fails, restart the transaction & regain write access for the
+ * buffer head which is used for block_bitmap modifications.
+@@ -834,6 +816,7 @@ int ext3_group_add(struct super_block *s
gdp->bg_inode_table = cpu_to_le32(input->inode_table);
gdp->bg_free_blocks_count = cpu_to_le16(input->free_blocks_count);
gdp->bg_free_inodes_count = cpu_to_le16(EXT3_INODES_PER_GROUP(sb));
/*
* Make the new blocks and inodes valid next. We do this before
-Index: linux-2.6.18.8.orig/fs/ext3/super.c
+Index: linux-2.6.18-53.1.14/fs/ext3/super.c
===================================================================
---- linux-2.6.18.8.orig.orig/fs/ext3/super.c 2007-07-02 11:09:26.000000000 +0200
-+++ linux-2.6.18.8.orig/fs/ext3/super.c 2007-07-02 11:18:04.000000000 +0200
+--- linux-2.6.18-53.1.14.orig/fs/ext3/super.c
++++ linux-2.6.18-53.1.14/fs/ext3/super.c
@@ -41,6 +41,7 @@
#include "xattr.h"
#include "acl.h"
static int ext3_load_journal(struct super_block *, struct ext3_super_block *,
unsigned long journal_devnum);
-@@ -1225,6 +1226,91 @@ static int ext3_setup_super(struct super
+@@ -1227,6 +1228,91 @@ static int ext3_setup_super(struct super
return res;
}
/* Called at mount-time, super-block is locked */
static int ext3_check_descriptors (struct super_block * sb)
{
-@@ -1274,6 +1360,13 @@ static int ext3_check_descriptors (struc
+@@ -1281,6 +1367,13 @@ static int ext3_check_descriptors (struc
le32_to_cpu(gdp->bg_inode_table));
return 0;
}
+ le16_to_cpu(gdp->bg_checksum));
+ return 0;
+ }
- block += EXT3_BLOCKS_PER_GROUP(sb);
+ first_block += EXT3_BLOCKS_PER_GROUP(sb);
gdp++;
}
-Index: linux-2.6.18.8.orig/fs/ext3/group.h
+Index: linux-2.6.18-53.1.14/fs/ext3/group.h
===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.18.8.orig/fs/ext3/group.h 2007-07-02 11:09:26.000000000 +0200
-@@ -0,0 +1,29 @@
+--- /dev/null
++++ linux-2.6.18-53.1.14/fs/ext3/group.h
+@@ -0,0 +1,30 @@
+/*
+ * linux/fs/ext3/group.h
+ *
-+ * Copyright (C) 2007 Cluster File Systems, Inc
++ * Copyright 2008 Sun Microsystems, Inc.
+ *
+ * Author: Andreas Dilger <adilger@clusterfs.com>
+ */
+extern unsigned ext3_init_inode_bitmap(struct super_block *sb,
+ struct buffer_head *bh, int group,
+ struct ext3_group_desc *desc);
++extern void mark_bitmap_end(int start_bit, int end_bit, char *bitmap);
+#endif /* _LINUX_EXT3_GROUP_H */
-Index: linux-2.6.18.8.orig/fs/ext3/ialloc.c
+Index: linux-2.6.18-53.1.14/fs/ext3/ialloc.c
===================================================================
---- linux-2.6.18.8.orig.orig/fs/ext3/ialloc.c 2007-07-02 11:09:26.000000000 +0200
-+++ linux-2.6.18.8.orig/fs/ext3/ialloc.c 2007-07-02 11:19:43.000000000 +0200
+--- linux-2.6.18-53.1.14.orig/fs/ext3/ialloc.c
++++ linux-2.6.18-53.1.14/fs/ext3/ialloc.c
@@ -28,6 +28,7 @@
#include "xattr.h"
+ * need to use it within a single byte (to ensure we get endianness right).
+ * We can use memset for the rest of the bitmap as there are no other users.
+ */
-+static void mark_bitmap_end(int start_bit, int end_bit, char *bitmap)
++void mark_bitmap_end(int start_bit, int end_bit, char *bitmap)
+{
+ int i;
+
+ if (EXT3_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) {
+ if (gdp->bg_flags & cpu_to_le16(EXT3_BG_INODE_UNINIT)) {
+ gdp->bg_flags &= cpu_to_le16(~EXT3_BG_INODE_UNINIT);
-+ free = EXT3_INODES_PER_GROUP(sb);
++ free = 0;
+ } else {
+ free = EXT3_INODES_PER_GROUP(sb) -
+ le16_to_cpu(gdp->bg_itable_unused);
- inode->i_ino = ino;
+ inode->i_ino = ino + group * EXT3_INODES_PER_GROUP(sb);
/* This is the optimal IO size (for stat), not the fs block size */
- inode->i_blksize = PAGE_SIZE;
inode->i_blocks = 0;
-Index: linux-2.6.18.8.orig/fs/ext3/mballoc.c
+ inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
+Index: linux-2.6.18-53.1.14/fs/ext3/mballoc.c
===================================================================
---- linux-2.6.18.8.orig.orig/fs/ext3/mballoc.c 2007-07-02 11:09:25.000000000 +0200
-+++ linux-2.6.18.8.orig/fs/ext3/mballoc.c 2007-07-02 11:09:26.000000000 +0200
+--- linux-2.6.18-53.1.14.orig/fs/ext3/mballoc.c
++++ linux-2.6.18-53.1.14/fs/ext3/mballoc.c
@@ -36,6 +36,8 @@
#include <linux/seq_file.h>
#include <linux/version.h>
unsigned short bb_first_free;
unsigned short bb_free;
unsigned short bb_fragments;
-@@ -943,10 +946,7 @@ static int ext3_mb_init_cache(struct pag
+@@ -941,10 +944,7 @@ static int ext3_mb_init_cache(struct pag
if (first_group + i >= EXT3_SB(sb)->s_groups_count)
break;
err = -ENOMEM;
bh[i] = sb_getblk(sb, le32_to_cpu(desc->bg_block_bitmap));
-@@ -961,7 +961,12 @@ static int ext3_mb_init_cache(struct pag
+@@ -959,7 +959,12 @@ static int ext3_mb_init_cache(struct pag
unlock_buffer(bh[i]);
continue;
}
get_bh(bh[i]);
bh[i]->b_end_io = end_buffer_read_sync;
submit_bh(READ, bh[i]);
-@@ -1732,6 +1737,10 @@ static int ext3_mb_good_group(struct ext
+@@ -1731,6 +1736,10 @@ static int ext3_mb_good_group(struct ext
switch (cr) {
case 0:
BUG_ON(ac->ac_2order == 0);
bits = ac->ac_sb->s_blocksize_bits + 1;
for (i = ac->ac_2order; i <= bits; i++)
if (grp->bb_counters[i] > 0)
-@@ -1825,7 +1834,9 @@ repeat:
+@@ -1824,7 +1833,9 @@ repeat:
}
ac->ac_groups_scanned++;
set_bit(EXT3_GROUP_INFO_NEED_INIT_BIT,
&meta_group_info[j]->bb_state);
-@@ -2972,9 +2984,17 @@ int ext3_mb_mark_diskspace_used(struct e
- mb_set_bits(bitmap_bh->b_data, ac->ac_b_ex.fe_start, ac->ac_b_ex.fe_len);
+@@ -2943,9 +2955,17 @@ int ext3_mb_mark_diskspace_used(struct e
+ mb_set_bits(NULL, bitmap_bh->b_data,
+ ac->ac_b_ex.fe_start, ac->ac_b_ex.fe_len);
- spin_lock(sb_bgl_lock(sbi, ac->ac_b_ex.fe_group));
+ if (gdp->bg_flags & cpu_to_le16(EXT3_BG_BLOCK_UNINIT)) {
+ gdp->bg_flags &= cpu_to_le16(~EXT3_BG_BLOCK_UNINIT);
+ gdp->bg_free_blocks_count =
spin_unlock(sb_bgl_lock(sbi, ac->ac_b_ex.fe_group));
percpu_counter_mod(&sbi->s_freeblocks_counter, - ac->ac_b_ex.fe_len);
-@@ -4343,6 +4363,7 @@ do_more:
+@@ -4355,6 +4375,7 @@ do_more:
spin_lock(sb_bgl_lock(sbi, block_group));
gdp->bg_free_blocks_count =
cpu_to_le16(le16_to_cpu(gdp->bg_free_blocks_count) + count);
spin_unlock(sb_bgl_lock(sbi, block_group));
percpu_counter_mod(&sbi->s_freeblocks_counter, count);
-Index: linux-2.6.18.8.orig/fs/ext3/balloc.c
+Index: linux-2.6.18-53.1.14/fs/ext3/balloc.c
===================================================================
---- linux-2.6.18.8.orig.orig/fs/ext3/balloc.c 2007-07-02 11:09:25.000000000 +0200
-+++ linux-2.6.18.8.orig/fs/ext3/balloc.c 2007-07-02 11:09:26.000000000 +0200
+--- linux-2.6.18-53.1.14.orig/fs/ext3/balloc.c
++++ linux-2.6.18-53.1.14/fs/ext3/balloc.c
@@ -20,6 +20,7 @@
#include <linux/quotaops.h>
#include <linux/buffer_head.h>
/*
* balloc.c contains the blocks allocation and deallocation routines
*/
-@@ -73,6 +74,75 @@ struct ext3_group_desc * ext3_get_group_
+@@ -73,6 +74,83 @@ struct ext3_group_desc * ext3_get_group_
return desc + offset;
}
+ for (bit = le32_to_cpu(gdp->bg_inode_table) - start,
+ bit_max = bit + sbi->s_itb_per_group; bit < bit_max; bit++)
+ ext3_set_bit(bit, bh->b_data);
++
++ /*
++ * Also if the number of blocks within the group is
++ * less than the blocksize * 8 ( which is the size
++ * of bitmap ), set rest of the block bitmap to 1
++ */
++ mark_bitmap_end(EXT3_BLOCKS_PER_GROUP(sb), sb->s_blocksize * 8,
++ bh->b_data);
+ }
+
+ return free_blocks - sbi->s_itb_per_group - 2;
/*
* Read the bitmap for a given block_group, reading into the specified
* slot in the superblock's bitmap cache.
-@@ -88,7 +158,19 @@ read_block_bitmap(struct super_block *sb
+@@ -88,7 +166,19 @@ read_block_bitmap(struct super_block *sb
desc = ext3_get_group_desc (sb, block_group, NULL);
if (!desc)
goto error_out;
if (!bh)
ext3_error (sb, "read_block_bitmap",
"Cannot read block bitmap - "
-@@ -467,6 +549,7 @@ do_more:
+@@ -467,6 +557,7 @@ do_more:
desc->bg_free_blocks_count =
cpu_to_le16(le16_to_cpu(desc->bg_free_blocks_count) +
group_freed);
spin_unlock(sb_bgl_lock(sbi, block_group));
percpu_counter_mod(&sbi->s_freeblocks_counter, count);
-@@ -1433,8 +1516,11 @@ allocated:
+@@ -1434,8 +1525,11 @@ allocated:
ret_block, goal_hits, goal_attempts);
spin_lock(sb_bgl_lock(sbi, group_no));