📄 ext3-uninit-2.6.9.patch
字号:
Add support for the uninit_groups feature to the kernel.Keep a high water mark of used inodes for each group to improve e2fsck time.Block and inode bitmaps can be uninitialized on disk via a flag in thegroup descriptor to avoid reading or scanning them at e2fsck time.A checksum of each group descriptor is used to ensure that corruption inthe group descriptor's bit flags does not cause incorrect operation.Index: linux-2.6.9-full/include/linux/ext3_fs.h===================================================================--- linux-2.6.9-full.orig/include/linux/ext3_fs.h 2007-03-28 18:35:41.000000000 +0400+++ linux-2.6.9-full/include/linux/ext3_fs.h 2007-03-28 18:36:16.000000000 +0400@@ -153,16 +153,22 @@ struct ext3_allocation_request { */ struct ext3_group_desc {- __le32 bg_block_bitmap; /* Blocks bitmap block */- __le32 bg_inode_bitmap; /* Inodes bitmap block */+ __le32 bg_block_bitmap; /* Blocks bitmap block */+ __le32 bg_inode_bitmap; /* Inodes bitmap block */ __le32 bg_inode_table; /* Inodes table block */ __le16 bg_free_blocks_count; /* Free blocks count */ __le16 bg_free_inodes_count; /* Free inodes count */ __le16 bg_used_dirs_count; /* Directories count */- __u16 bg_pad;- __le32 bg_reserved[3];+ __le16 bg_flags; /* EXT3_BG_flags (UNINIT, etc) */+ __le32 bg_reserved[2]; /* Likely block/inode bitmap checksum */+ __le16 bg_itable_unused; /* Unused inodes count */+ __le16 bg_checksum; /* crc16(sb_uuid+group+desc) */ }; +#define EXT3_BG_INODE_UNINIT 0x0001 /* Inode table/bitmap not in use */+#define EXT3_BG_BLOCK_UNINIT 0x0002 /* Block bitmap not in use */+#define EXT3_BG_INODE_ZEROED 0x0004 /* On-disk itable initialized to zero */+ /* * Macro-instructions used to manage group descriptors */@@ -572,6 +578,7 @@ static inline struct ext3_inode_info *EX #define EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001 #define EXT3_FEATURE_RO_COMPAT_LARGE_FILE 0x0002 #define EXT3_FEATURE_RO_COMPAT_BTREE_DIR 0x0004+#define EXT4_FEATURE_RO_COMPAT_GDT_CSUM 0x0010 #define EXT4_FEATURE_RO_COMPAT_DIR_NLINK 0x0020 #define EXT3_FEATURE_INCOMPAT_COMPRESSION 0x0001@@ -588,6 +595,7 @@ static inline struct ext3_inode_info *EX EXT3_FEATURE_INCOMPAT_EXTENTS) #define EXT3_FEATURE_RO_COMPAT_SUPP (EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER| \ EXT3_FEATURE_RO_COMPAT_LARGE_FILE| \+ EXT4_FEATURE_RO_COMPAT_GDT_CSUM| \ EXT4_FEATURE_RO_COMPAT_DIR_NLINK| \ EXT3_FEATURE_RO_COMPAT_BTREE_DIR) Index: linux-2.6.9-full/fs/ext3/resize.c===================================================================--- linux-2.6.9-full.orig/fs/ext3/resize.c 2006-03-10 18:20:03.000000000 +0300+++ linux-2.6.9-full/fs/ext3/resize.c 2007-03-28 18:36:16.000000000 +0400@@ -19,6 +19,7 @@ #include <linux/errno.h> #include <linux/slab.h> +#include "group.h" #define outside(b, first, last) ((b) < (first) || (b) >= (last)) #define inside(b, first, last) ((b) >= (first) && (b) < (last))@@ -807,6 +808,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));+ gdp->bg_checksum = ext3_group_desc_csum(sbi, input->group, gdp); /* * Make the new blocks and inodes valid next. We do this beforeIndex: linux-2.6.9-full/fs/ext3/super.c===================================================================--- linux-2.6.9-full.orig/fs/ext3/super.c 2007-03-28 18:35:42.000000000 +0400+++ linux-2.6.9-full/fs/ext3/super.c 2007-03-28 18:36:16.000000000 +0400@@ -38,6 +38,7 @@ #include <asm/uaccess.h> #include "xattr.h" #include "acl.h"+#include "group.h" static int ext3_load_journal(struct super_block *, struct ext3_super_block *, unsigned long journal_devnum);@@ -1090,6 +1091,90 @@ static int ext3_setup_super(struct super return res; } +#if !defined(CONFIG_CRC16) && !defined(CONFIG_CRC16_MODULE)+/** CRC table for the CRC-16. The poly is 0x8005 (x^16 + x^15 + x^2 + 1) */+__u16 const crc16_table[256] = {+ 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,+ 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,+ 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,+ 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,+ 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,+ 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,+ 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,+ 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,+ 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,+ 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,+ 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,+ 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,+ 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,+ 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,+ 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,+ 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,+ 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,+ 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,+ 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,+ 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,+ 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,+ 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,+ 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,+ 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,+ 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,+ 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,+ 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,+ 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,+ 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,+ 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,+ 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,+ 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040+};++static inline __u16 crc16_byte(__u16 crc, const __u8 data)+{+ return (crc >> 8) ^ crc16_table[(crc ^ data) & 0xff];+}++__u16 crc16(__u16 crc, __u8 const *buffer, size_t len)+{+ while (len--)+ crc = crc16_byte(crc, *buffer++);+ return crc;+}+#endif++__le16 ext3_group_desc_csum(struct ext3_sb_info *sbi, __u32 block_group,+ struct ext3_group_desc *gdp)+{+ __u16 crc = 0;++ if (sbi->s_es->s_feature_ro_compat &+ cpu_to_le32(EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) {+ int offset = offsetof(struct ext3_group_desc, bg_checksum);+ __le32 le_group = cpu_to_le32(block_group);++ crc = crc16(~0, sbi->s_es->s_uuid, sizeof(sbi->s_es->s_uuid));+ crc = crc16(crc, (__u8 *)&le_group, sizeof(le_group));+ crc = crc16(crc, (__u8 *)gdp, offset);+ offset += sizeof(gdp->bg_checksum); /* skip checksum */+ BUG_ON(offset != sizeof(*gdp)); /* XXX handle s_desc_size */+ /* for checksum of struct ext4_group_desc do the rest...+ if (offset < sbi->s_es->s_desc_size) {+ crc = crc16(crc, (__u8 *)gdp + offset,+ sbi->s_es->s_desc_size - offset);+ */+ }++ return cpu_to_le16(crc);+}++int ext3_group_desc_csum_verify(struct ext3_sb_info *sbi, __u32 block_group,+ struct ext3_group_desc *gdp)+{+ if (gdp->bg_checksum != ext3_group_desc_csum(sbi, block_group, gdp))+ return 0;++ return 1;+}+ /* Called at mount-time, super-block is locked */ static int ext3_check_descriptors (struct super_block * sb) {@@ -1139,6 +1224,13 @@ static int ext3_check_descriptors (struc le32_to_cpu(gdp->bg_inode_table)); return 0; }+ if (!ext3_group_desc_csum_verify(sbi, i, gdp)) {+ ext3_error(sb, __FUNCTION__,+ "Checksum for group %d failed (%u!=%u)\n", i,+ le16_to_cpu(ext3_group_desc_csum(sbi,i,gdp)),+ le16_to_cpu(gdp->bg_checksum));+ return 0;+ } block += EXT3_BLOCKS_PER_GROUP(sb); gdp++; }Index: linux-2.6.9-full/fs/ext3/group.h===================================================================--- linux-2.6.9-full.orig/fs/ext3/group.h 2007-02-13 18:39:59.640066087 +0300+++ linux-2.6.9-full/fs/ext3/group.h 2007-03-28 18:36:16.000000000 +0400@@ -0,0 +1,29 @@+/*+ * linux/fs/ext3/group.h+ *+ * Copyright (C) 2007 Cluster File Systems, Inc+ *+ * Author: Andreas Dilger <adilger@clusterfs.com>+ */++#ifndef _LINUX_EXT3_GROUP_H+#define _LINUX_EXT3_GROUP_H+#if defined(CONFIG_CRC16) || defined(CONFIG_CRC16_MODULE)+#include <linux/crc16.h>+#endif++extern __le16 ext3_group_desc_csum(struct ext3_sb_info *sbi, __u32 group,+ struct ext3_group_desc *gdp);+extern int ext3_group_desc_csum_verify(struct ext3_sb_info *sbi, __u32 group,+ struct ext3_group_desc *gdp);+struct buffer_head *read_block_bitmap(struct super_block *sb,+ unsigned int block_group);+extern unsigned ext3_init_block_bitmap(struct super_block *sb,+ struct buffer_head *bh, int group,+ struct ext3_group_desc *desc);+#define ext3_free_blocks_after_init(sb, group, desc) \+ ext3_init_block_bitmap(sb, NULL, group, desc)+extern unsigned ext3_init_inode_bitmap(struct super_block *sb,+ struct buffer_head *bh, int group,+ struct ext3_group_desc *desc);+#endif /* _LINUX_EXT3_GROUP_H */Index: linux-2.6.9-full/fs/ext3/ialloc.c===================================================================--- linux-2.6.9-full.orig/fs/ext3/ialloc.c 2007-03-28 18:35:38.000000000 +0400+++ linux-2.6.9-full/fs/ext3/ialloc.c 2007-03-28 18:36:16.000000000 +0400@@ -28,6 +28,7 @@ #include "xattr.h" #include "acl.h"+#include "group.h" /* * ialloc.c contains the inodes allocation and deallocation routines@@ -43,6 +44,52 @@ * the free blocks count in the block. */ +/*+ * 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);+}++/* Initializes an uninitialized inode bitmap */+unsigned ext3_init_inode_bitmap(struct super_block *sb,+ struct buffer_head *bh, int block_group,+ struct ext3_group_desc *gdp)+{+ struct ext3_sb_info *sbi = EXT3_SB(sb);++ J_ASSERT_BH(bh, buffer_locked(bh));++ /* If checksum is bad mark all blocks and inodes 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, (EXT3_INODES_PER_GROUP(sb) + 7) / 8);+ mark_bitmap_end(EXT3_INODES_PER_GROUP(sb), EXT3_BLOCKS_PER_GROUP(sb),+ bh->b_data);++ return EXT3_INODES_PER_GROUP(sb);+} /* * Read the inode allocation bitmap for a given block_group, reading@@ -59,8 +106,19 @@ read_inode_bitmap(struct super_block * s desc = ext3_get_group_desc(sb, block_group, NULL); if (!desc) goto error_out;-- bh = sb_bread(sb, le32_to_cpu(desc->bg_inode_bitmap));+ if (desc->bg_flags & cpu_to_le16(EXT3_BG_INODE_UNINIT)) {+ bh = sb_getblk(sb, le32_to_cpu(desc->bg_inode_bitmap));+ if (!buffer_uptodate(bh)) {+ lock_buffer(bh);+ if (!buffer_uptodate(bh)) {+ ext3_init_inode_bitmap(sb, bh,block_group,desc);+ set_buffer_uptodate(bh);+ }+ unlock_buffer(bh);+ }+ } else {+ bh = sb_bread(sb, le32_to_cpu(desc->bg_inode_bitmap));+ } if (!bh) ext3_error(sb, "read_inode_bitmap", "Cannot read inode bitmap - "@@ -169,6 +227,8 @@ void ext3_free_inode (handle_t *handle, if (is_directory) 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,block_group,+ gdp); spin_unlock(sb_bgl_lock(sbi, block_group)); percpu_counter_inc(&sbi->s_freeinodes_counter); if (is_directory)@@ -453,7 +513,7 @@ struct inode *ext3_new_inode(handle_t *h struct ext3_sb_info *sbi; int err = 0; struct inode *ret;- int i;+ int i, free = 0; /* Cannot create files in a deleted directory */ if (!dir || !dir->i_nlink)@@ -566,11 +626,13 @@ repeat_in_this_group: goto out;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -