📄 ext3-uninit-2.6.9.patch
字号:
got:- ino += group * EXT3_INODES_PER_GROUP(sb) + 1;- if (ino < EXT3_FIRST_INO(sb) || ino > le32_to_cpu(es->s_inodes_count)) {- ext3_error (sb, "ext3_new_inode",- "reserved inode or inode > inodes count - "- "block_group = %d, inode=%lu", group, ino);+ ino++;+ if ((group == 0 && ino < EXT3_FIRST_INO(sb)) ||+ ino > EXT3_INODES_PER_GROUP(sb)) {+ ext3_error(sb, __FUNCTION__,+ "reserved inode or inode > inodes count - "+ "block_group = %d, inode=%lu", group,+ ino + group * EXT3_INODES_PER_GROUP(sb)); err = -EIO; goto fail; }@@ -578,13 +640,65 @@ got: BUFFER_TRACE(bh2, "get_write_access"); err = ext3_journal_get_write_access(handle, bh2); if (err) goto fail;++ /* We may have to initialize the block bitmap if it isn't already */+ if (EXT3_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_GDT_CSUM) &&+ gdp->bg_flags & cpu_to_le16(EXT3_BG_BLOCK_UNINIT)) {+ struct buffer_head *block_bh = read_block_bitmap(sb, group);++ BUFFER_TRACE(block_bh, "get block bitmap access");+ err = ext3_journal_get_write_access(handle, block_bh);+ if (err) {+ brelse(block_bh);+ goto fail;+ }++ free = 0;+ spin_lock(sb_bgl_lock(sbi, group));+ /* recheck and clear flag under lock if we still need to */+ if (gdp->bg_flags & cpu_to_le16(EXT3_BG_BLOCK_UNINIT)) {+ gdp->bg_flags &= cpu_to_le16(~EXT3_BG_BLOCK_UNINIT);+ free = ext3_free_blocks_after_init(sb, group, gdp);+ gdp->bg_free_blocks_count = cpu_to_le16(free);+ }+ spin_unlock(sb_bgl_lock(sbi, group));++ /* Don't need to dirty bitmap block if we didn't change it */+ if (free) {+ BUFFER_TRACE(block_bh, "dirty block bitmap");+ err = ext3_journal_dirty_metadata(handle, block_bh);+ }++ brelse(block_bh);+ if (err)+ goto fail;+ }+ spin_lock(sb_bgl_lock(sbi, group));+ /* If we didn't allocate from within the initialized part of the inode+ * table then we need to initialize up to this inode. */+ 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 = 0;+ } else {+ free = EXT3_INODES_PER_GROUP(sb) -+ le16_to_cpu(gdp->bg_itable_unused);+ }++ if (ino > free) {+ gdp->bg_itable_unused =+ cpu_to_le16(EXT3_INODES_PER_GROUP(sb) - ino);+ }+ }+ gdp->bg_free_inodes_count = cpu_to_le16(le16_to_cpu(gdp->bg_free_inodes_count) - 1); if (S_ISDIR(mode)) { gdp->bg_used_dirs_count = cpu_to_le16(le16_to_cpu(gdp->bg_used_dirs_count) + 1); }+ gdp->bg_checksum = ext3_group_desc_csum(sbi, group, gdp); spin_unlock(sb_bgl_lock(sbi, group)); BUFFER_TRACE(bh2, "call ext3_journal_dirty_metadata"); err = ext3_journal_dirty_metadata(handle, bh2);@@ -606,7 +720,7 @@ got: inode->i_gid = current->fsgid; inode->i_mode = mode; - 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.9-full/fs/ext3/mballoc.c===================================================================--- linux-2.6.9-full.orig/fs/ext3/mballoc.c 2007-03-28 15:42:45.000000000 +0400+++ linux-2.6.9-full/fs/ext3/mballoc.c 2007-03-28 18:36:16.000000000 +0400@@ -36,6 +36,8 @@ #include <linux/seq_file.h> #include <linux/version.h> +#include "group.h"+ /* * MUSTDO: * - test ext3_ext_search_left() and ext3_ext_search_right()@@ -323,6 +325,7 @@ struct ext3_group_info { unsigned long bb_state; unsigned long bb_tid; struct ext3_free_metadata *bb_md_cur;+ struct ext3_group_desc *bb_gdp; unsigned short bb_first_free; unsigned short bb_free; unsigned short bb_fragments;@@ -928,10 +931,7 @@ static int ext3_mb_init_cache(struct pag if (first_group + i >= EXT3_SB(sb)->s_groups_count) break; - err = -EIO;- desc = ext3_get_group_desc(sb, first_group + i, NULL);- if (desc == NULL)- goto out;+ desc = EXT3_GROUP_INFO(sb, first_group + i)->bb_gdp; err = -ENOMEM; bh[i] = sb_getblk(sb, le32_to_cpu(desc->bg_block_bitmap));@@ -946,7 +946,12 @@ static int ext3_mb_init_cache(struct pag unlock_buffer(bh[i]); continue; }-+ if (desc->bg_flags & cpu_to_le16(EXT3_BG_BLOCK_UNINIT)) {+ ext3_init_block_bitmap(sb, bh[i], first_group + i,desc);+ set_buffer_uptodate(bh[i]);+ unlock_buffer(bh[i]);+ continue;+ } get_bh(bh[i]); bh[i]->b_end_io = end_buffer_read_sync; submit_bh(READ, bh[i]);@@ -1703,6 +1708,10 @@ static int ext3_mb_good_group(struct ext switch (cr) { case 0: BUG_ON(ac->ac_2order == 0);+ /* If this group is uninitialized, skip it initially */+ if (grp->bb_gdp->bg_flags &+ cpu_to_le16(EXT3_BG_BLOCK_UNINIT))+ return 0; bits = ac->ac_sb->s_blocksize_bits + 1; for (i = ac->ac_2order; i <= bits; i++) if (grp->bb_counters[i] > 0)@@ -1796,7 +1805,9 @@ repeat: } ac->ac_groups_scanned++;- if (cr == 0)+ if (cr == 0 || (e3b.bd_info->bb_gdp->bg_flags &+ cpu_to_le16(EXT3_BG_BLOCK_UNINIT) &&+ ac->ac_2order != 0)) ext3_mb_simple_scan_group(ac, &e3b); else if (cr == 1 && ac->ac_g_ex.fe_len == sbi->s_stripe) ext3_mb_scan_aligned(ac, &e3b);@@ -2267,12 +2278,13 @@ int ext3_mb_init_backend(struct super_bl i--; goto err_freebuddy; }+ memset(meta_group_info[j], 0, len); desc = ext3_get_group_desc(sb, i, NULL);+ meta_group_info[j]->bb_gdp = desc; if (desc == NULL) { printk(KERN_ERR"EXT3-fs: can't read descriptor %u\n",i); goto err_freebuddy; }- memset(meta_group_info[j], 0, len); set_bit(EXT3_GROUP_INFO_NEED_INIT_BIT, &meta_group_info[j]->bb_state); @@ -2936,9 +2948,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); 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 =+ cpu_to_le16(ext3_free_blocks_after_init(sb,+ ac->ac_b_ex.fe_group,+ gdp));+ } gdp->bg_free_blocks_count = cpu_to_le16(le16_to_cpu(gdp->bg_free_blocks_count) - ac->ac_b_ex.fe_len);+ gdp->bg_checksum = ext3_group_desc_csum(sbi, ac->ac_b_ex.fe_group, gdp); 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); @@ -4303,6 +4323,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);+ gdp->bg_checksum = ext3_group_desc_csum(sbi, block_group, gdp); spin_unlock(sb_bgl_lock(sbi, block_group)); percpu_counter_mod(&sbi->s_freeblocks_counter, count); Index: linux-2.6.9-full/fs/ext3/balloc.c===================================================================--- linux-2.6.9-full.orig/fs/ext3/balloc.c 2007-03-28 15:45:41.000000000 +0400+++ linux-2.6.9-full/fs/ext3/balloc.c 2007-03-28 18:36:16.000000000 +0400@@ -20,6 +20,7 @@ #include <linux/quotaops.h> #include <linux/buffer_head.h> +#include "group.h" /* * balloc.c contains the blocks allocation and deallocation routines */@@ -73,6 +74,75 @@ struct ext3_group_desc * ext3_get_group_ return gdp + desc; } +/* Initializes an uninitialized block bitmap if given, and returns the+ * number of blocks free in the group. */+unsigned ext3_init_block_bitmap(struct super_block *sb, struct buffer_head *bh,+ int block_group, struct ext3_group_desc *gdp)+{+ unsigned long start;+ int bit, bit_max;+ unsigned free_blocks;+ struct ext3_sb_info *sbi = EXT3_SB(sb);++ if (bh) {+ J_ASSERT_BH(bh, buffer_locked(bh));++ /* If checksum is bad mark all blocks use to prevent allocation,+ * essentially implementing a per-group read-only flag. */+ if (!ext3_group_desc_csum_verify(sbi, block_group, gdp)) {+ ext3_error(sb, __FUNCTION__,+ "Checksum bad for group %u\n", block_group);+ gdp->bg_free_blocks_count = 0;+ gdp->bg_free_inodes_count = 0;+ gdp->bg_itable_unused = 0;+ memset(bh->b_data, 0xff, sb->s_blocksize);+ return 0;+ }+ memset(bh->b_data, 0, sb->s_blocksize);+ }++ /* Check for superblock and gdt backups in this group */+ bit_max = ext3_bg_has_super(sb, block_group);++ if (!EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_META_BG) ||+ block_group < le32_to_cpu(sbi->s_es->s_first_meta_bg) *+ sbi->s_desc_per_block) {+ if (bit_max) {+ bit_max += ext3_bg_num_gdb(sb, block_group);+ bit_max +=le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks);+ }+ } else { /* For META_BG_BLOCK_GROUPS */+ int group_rel = (block_group -+ le32_to_cpu(sbi->s_es->s_first_meta_bg)) %+ EXT3_DESC_PER_BLOCK(sb);+ if (group_rel == 0 || group_rel == 1 ||+ (group_rel == EXT3_DESC_PER_BLOCK(sb) - 1))+ bit_max += 1;+ }++ /* Last and first groups are always initialized */+ free_blocks = EXT3_BLOCKS_PER_GROUP(sb) - bit_max;++ if (bh) {+ for (bit = 0; bit < bit_max; bit++)+ ext3_set_bit(bit, bh->b_data);++ start = block_group * EXT3_BLOCKS_PER_GROUP(sb) ++ le32_to_cpu(sbi->s_es->s_first_data_block);++ /* Set bits for block and inode bitmaps, and inode table */+ ext3_set_bit(le32_to_cpu(gdp->bg_block_bitmap) - start,+ bh->b_data);+ ext3_set_bit(le32_to_cpu(gdp->bg_inode_bitmap) - start,+ bh->b_data);+ 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);+ }++ 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 desc = ext3_get_group_desc (sb, block_group, NULL); if (!desc) goto error_out;- bh = sb_bread(sb, le32_to_cpu(desc->bg_block_bitmap));+ if (desc->bg_flags & cpu_to_le16(EXT3_BG_BLOCK_UNINIT)) {+ bh = sb_getblk(sb, le32_to_cpu(desc->bg_block_bitmap));+ if (!buffer_uptodate(bh)) {+ lock_buffer(bh);+ if (!buffer_uptodate(bh)) {+ ext3_init_block_bitmap(sb, bh,block_group,desc);+ set_buffer_uptodate(bh);+ }+ unlock_buffer(bh);+ }+ } else {+ bh = sb_bread(sb, le32_to_cpu(desc->bg_block_bitmap));+ } if (!bh) ext3_error (sb, "read_block_bitmap", "Cannot read block bitmap - "@@ -429,6 +511,7 @@ do_more: gdp->bg_free_blocks_count = cpu_to_le16(le16_to_cpu(gdp->bg_free_blocks_count) + *pdquot_freed_blocks);+ gdp->bg_checksum = ext3_group_desc_csum(sbi, block_group, gdp); spin_unlock(sb_bgl_lock(sbi, block_group)); percpu_counter_mod(&sbi->s_freeblocks_counter, count); @@ -1330,8 +1413,11 @@ allocated: ret_block, goal_hits, goal_attempts); spin_lock(sb_bgl_lock(sbi, group_no));+ 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 = cpu_to_le16(le16_to_cpu(gdp->bg_free_blocks_count) - 1);+ gdp->bg_checksum = ext3_group_desc_csum(sbi, group_no, gdp); spin_unlock(sb_bgl_lock(sbi, group_no)); percpu_counter_mod(&sbi->s_freeblocks_counter, -1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -