From 5ee2e1cdf3ce600f91f777b76c2e676bf5c295d9 Mon Sep 17 00:00:00 2001 From: johann Date: Wed, 24 Jun 2009 22:48:19 +0000 Subject: [PATCH 1/1] Branch b1_8 b=19875 backport patches to RHEL5/ext4. --- .../patches/ext4-convert-group-lock-rhel5.patch | 595 +++++++++++++++++++++ .../patches/ext4-mballoc-extra-checks-rhel5.patch | 35 +- .../series/ldiskfs-2.6-rhel5-ext4.series | 1 + 3 files changed, 614 insertions(+), 17 deletions(-) create mode 100644 ldiskfs/kernel_patches/patches/ext4-convert-group-lock-rhel5.patch diff --git a/ldiskfs/kernel_patches/patches/ext4-convert-group-lock-rhel5.patch b/ldiskfs/kernel_patches/patches/ext4-convert-group-lock-rhel5.patch new file mode 100644 index 0000000..370b2e7 --- /dev/null +++ b/ldiskfs/kernel_patches/patches/ext4-convert-group-lock-rhel5.patch @@ -0,0 +1,595 @@ +Index: linux-2.6.18-128.1.6/fs/ext4/balloc.c +=================================================================== +--- linux-2.6.18-128.1.6.orig/fs/ext4/balloc.c ++++ linux-2.6.18-128.1.6/fs/ext4/balloc.c +@@ -321,15 +321,15 @@ ext4_read_block_bitmap(struct super_bloc + if (bh_uptodate_or_lock(bh)) + return bh; + +- spin_lock(sb_bgl_lock(EXT4_SB(sb), block_group)); ++ ext4_lock_group(sb, block_group); + if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { + ext4_init_block_bitmap(sb, bh, block_group, desc); + set_buffer_uptodate(bh); + unlock_buffer(bh); +- spin_unlock(sb_bgl_lock(EXT4_SB(sb), block_group)); ++ ext4_unlock_group(sb, block_group); + return bh; + } +- spin_unlock(sb_bgl_lock(EXT4_SB(sb), block_group)); ++ ext4_unlock_group(sb, block_group); + if (bh_submit_read(bh) < 0) { + put_bh(bh); + ext4_error(sb, __func__, +@@ -778,8 +778,9 @@ do_more: + BUFFER_TRACE(bitmap_bh, "set in b_committed_data"); + J_ASSERT_BH(bitmap_bh, + bh2jh(bitmap_bh)->b_committed_data != NULL); +- ext4_set_bit_atomic(sb_bgl_lock(sbi, block_group), bit + i, +- bh2jh(bitmap_bh)->b_committed_data); ++ ext4_set_bit_atomic(ext4_group_lock_ptr(sb, block_group), ++ bit + i, ++ bh2jh(bitmap_bh)->b_committed_data); + + /* + * We clear the bit in the bitmap after setting the committed +@@ -787,7 +788,7 @@ do_more: + * the allocator uses. + */ + BUFFER_TRACE(bitmap_bh, "clear bit"); +- if (!ext4_clear_bit_atomic(sb_bgl_lock(sbi, block_group), ++ if (!ext4_clear_bit_atomic(ext4_group_lock_ptr(sb, block_group), + bit + i, bitmap_bh->b_data)) { + jbd_unlock_bh_state(bitmap_bh); + ext4_error(sb, __func__, +@@ -801,17 +802,17 @@ do_more: + } + jbd_unlock_bh_state(bitmap_bh); + +- spin_lock(sb_bgl_lock(sbi, block_group)); ++ ext4_lock_group(sb, block_group); + le16_add_cpu(&desc->bg_free_blocks_count, group_freed); + desc->bg_checksum = ext4_group_desc_csum(sbi, block_group, desc); +- spin_unlock(sb_bgl_lock(sbi, block_group)); ++ ext4_unlock_group(sb, block_group); + percpu_counter_add(&sbi->s_freeblocks_counter, count); + + if (sbi->s_log_groups_per_flex) { + ext4_group_t flex_group = ext4_flex_group(sbi, block_group); +- spin_lock(sb_bgl_lock(sbi, flex_group)); ++ ext4_lock_group(sb, block_group); + sbi->s_flex_groups[flex_group].free_blocks += count; +- spin_unlock(sb_bgl_lock(sbi, flex_group)); ++ ext4_unlock_group(sb, block_group); + } + + /* We dirtied the bitmap block */ +@@ -1104,7 +1105,7 @@ repeat: + } + start = grp_goal; + +- if (!claim_block(sb_bgl_lock(EXT4_SB(sb), group), ++ if (!claim_block(ext4_group_lock_ptr(sb, group), + grp_goal, bitmap_bh)) { + /* + * The block was allocated by another thread, or it was +@@ -1120,7 +1121,7 @@ repeat: + grp_goal++; + while (num < *count && grp_goal < end + && ext4_test_allocatable(grp_goal, bitmap_bh) +- && claim_block(sb_bgl_lock(EXT4_SB(sb), group), ++ && claim_block(ext4_group_lock_ptr(sb, group), + grp_goal, bitmap_bh)) { + num++; + grp_goal++; +@@ -1872,7 +1873,7 @@ allocated: + } + } + jbd_lock_bh_state(bitmap_bh); +- spin_lock(sb_bgl_lock(sbi, group_no)); ++ ext4_lock_group(sb, group_no); + if (buffer_jbd(bitmap_bh) && bh2jh(bitmap_bh)->b_committed_data) { + int i; + +@@ -1885,7 +1886,7 @@ allocated: + } + } + ext4_debug("found bit %d\n", grp_alloc_blk); +- spin_unlock(sb_bgl_lock(sbi, group_no)); ++ ext4_unlock_group(sb, group_no); + jbd_unlock_bh_state(bitmap_bh); + #endif + +@@ -1902,19 +1903,19 @@ allocated: + * list of some description. We don't know in advance whether + * the caller wants to use it as metadata or data. + */ +- spin_lock(sb_bgl_lock(sbi, group_no)); ++ ext4_lock_group(sb, group_no); + if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) + gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT); + le16_add_cpu(&gdp->bg_free_blocks_count, -num); + gdp->bg_checksum = ext4_group_desc_csum(sbi, group_no, gdp); +- spin_unlock(sb_bgl_lock(sbi, group_no)); ++ ext4_unlock_group(sb, group_no); + percpu_counter_sub(&sbi->s_freeblocks_counter, num); + + if (sbi->s_log_groups_per_flex) { + ext4_group_t flex_group = ext4_flex_group(sbi, group_no); +- spin_lock(sb_bgl_lock(sbi, flex_group)); ++ ext4_lock_group(sb, flex_group); + sbi->s_flex_groups[flex_group].free_blocks -= num; +- spin_unlock(sb_bgl_lock(sbi, flex_group)); ++ ext4_unlock_group(sb, flex_group); + } + + BUFFER_TRACE(gdp_bh, "journal_dirty_metadata for group descriptor"); +Index: linux-2.6.18-128.1.6/fs/ext4/ialloc.c +=================================================================== +--- linux-2.6.18-128.1.6.orig/fs/ext4/ialloc.c ++++ linux-2.6.18-128.1.6/fs/ext4/ialloc.c +@@ -118,15 +118,15 @@ ext4_read_inode_bitmap(struct super_bloc + if (bh_uptodate_or_lock(bh)) + return bh; + +- spin_lock(sb_bgl_lock(EXT4_SB(sb), block_group)); ++ ext4_lock_group(sb, block_group); + if (desc->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) { + ext4_init_inode_bitmap(sb, bh, block_group, desc); + set_buffer_uptodate(bh); + unlock_buffer(bh); +- spin_unlock(sb_bgl_lock(EXT4_SB(sb), block_group)); ++ ext4_unlock_group(sb, block_group); + return bh; + } +- spin_unlock(sb_bgl_lock(EXT4_SB(sb), block_group)); ++ ext4_unlock_group(sb, block_group); + if (bh_submit_read(bh) < 0) { + put_bh(bh); + ext4_error(sb, __func__, +@@ -221,8 +221,8 @@ void ext4_free_inode (handle_t *handle, + goto error_return; + + /* Ok, now we can actually update the inode bitmaps.. */ +- if (!ext4_clear_bit_atomic(sb_bgl_lock(sbi, block_group), +- bit, bitmap_bh->b_data)) ++ if (!ext4_clear_bit_atomic(ext4_group_lock_ptr(sb, block_group), ++ bit, bitmap_bh->b_data)) + ext4_error (sb, "ext4_free_inode", + "bit already cleared for inode %lu", ino); + else { +@@ -233,22 +233,22 @@ void ext4_free_inode (handle_t *handle, + if (fatal) goto error_return; + + if (gdp) { +- spin_lock(sb_bgl_lock(sbi, block_group)); ++ ext4_lock_group(sb, block_group); + le16_add_cpu(&gdp->bg_free_inodes_count, 1); + if (is_directory) + le16_add_cpu(&gdp->bg_used_dirs_count, -1); + gdp->bg_checksum = ext4_group_desc_csum(sbi, + block_group, gdp); +- spin_unlock(sb_bgl_lock(sbi, block_group)); ++ ext4_unlock_group(sb, block_group); + percpu_counter_inc(&sbi->s_freeinodes_counter); + if (is_directory) + percpu_counter_dec(&sbi->s_dirs_counter); + + if (sbi->s_log_groups_per_flex) { + flex_group = ext4_flex_group(sbi, block_group); +- spin_lock(sb_bgl_lock(sbi, flex_group)); ++ ext4_lock_group(sb, flex_group); + sbi->s_flex_groups[flex_group].free_inodes++; +- spin_unlock(sb_bgl_lock(sbi, flex_group)); ++ ext4_unlock_group(sb, flex_group); + } + } + BUFFER_TRACE(bh2, "call ext4_journal_dirty_metadata"); +@@ -630,7 +630,7 @@ struct inode *ext4_new_inode(handle_t *h + if (err) + goto fail; + +- if (ext4_set_bit_atomic(sb_bgl_lock(sbi, group), ++ if (ext4_set_bit_atomic(ext4_group_lock_ptr(sb, group), + ino, bitmap_bh->b_data)) { + printk(KERN_ERR "goal inode %lu unavailable\n", goal); + /* Oh well, we tried. */ +@@ -691,7 +691,7 @@ repeat_in_this_group: + if (err) + goto fail; + +- if (!ext4_set_bit_atomic(sb_bgl_lock(sbi, group), ++ if (!ext4_set_bit_atomic(ext4_group_lock_ptr(sb, group), + ino, bitmap_bh->b_data)) { + /* we won it */ + BUFFER_TRACE(bitmap_bh, +@@ -751,14 +751,14 @@ got: + } + + free = 0; +- spin_lock(sb_bgl_lock(sbi, group)); ++ ext4_lock_group(sb, group); + /* recheck and clear flag under lock if we still need to */ + if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { + gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT); + free = ext4_free_blocks_after_init(sb, group, gdp); + gdp->bg_free_blocks_count = cpu_to_le16(free); + } +- spin_unlock(sb_bgl_lock(sbi, group)); ++ ext4_unlock_group(sb, group); + + /* Don't need to dirty bitmap block if we didn't change it */ + if (free) { +@@ -771,7 +771,7 @@ got: + goto fail; + } + +- spin_lock(sb_bgl_lock(sbi, group)); ++ ext4_lock_group(sb, 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 (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) { +@@ -807,7 +807,7 @@ got: + le16_add_cpu(&gdp->bg_used_dirs_count, 1); + } + gdp->bg_checksum = ext4_group_desc_csum(sbi, group, gdp); +- spin_unlock(sb_bgl_lock(sbi, group)); ++ ext4_unlock_group(sb, group); + BUFFER_TRACE(bh2, "call ext4_journal_dirty_metadata"); + err = ext4_journal_dirty_metadata(handle, bh2); + if (err) goto fail; +@@ -819,9 +819,9 @@ got: + + if (sbi->s_log_groups_per_flex) { + flex_group = ext4_flex_group(sbi, group); +- spin_lock(sb_bgl_lock(sbi, flex_group)); ++ ext4_lock_group(sb, flex_group); + sbi->s_flex_groups[flex_group].free_inodes--; +- spin_unlock(sb_bgl_lock(sbi, flex_group)); ++ ext4_unlock_group(sb, flex_group); + } + + inode->i_uid = current->fsuid; +Index: linux-2.6.18-128.1.6/fs/ext4/mballoc.c +=================================================================== +--- linux-2.6.18-128.1.6.orig/fs/ext4/mballoc.c ++++ linux-2.6.18-128.1.6/fs/ext4/mballoc.c +@@ -361,24 +361,12 @@ static inline void mb_set_bit(int bit, v + ext4_set_bit(bit, addr); + } + +-static inline void mb_set_bit_atomic(spinlock_t *lock, int bit, void *addr) +-{ +- addr = mb_correct_addr_and_bit(&bit, addr); +- ext4_set_bit_atomic(lock, bit, addr); +-} +- + static inline void mb_clear_bit(int bit, void *addr) + { + addr = mb_correct_addr_and_bit(&bit, addr); + ext4_clear_bit(bit, addr); + } + +-static inline void mb_clear_bit_atomic(spinlock_t *lock, int bit, void *addr) +-{ +- addr = mb_correct_addr_and_bit(&bit, addr); +- ext4_clear_bit_atomic(lock, bit, addr); +-} +- + static inline int mb_find_next_zero_bit(void *addr, int max, int start) + { + int fix = 0, ret, tmpmax; +@@ -789,16 +777,16 @@ static int ext4_mb_init_cache(struct pag + if (bh_uptodate_or_lock(bh[i])) + continue; + +- spin_lock(sb_bgl_lock(EXT4_SB(sb), first_group + i)); ++ ext4_lock_group(sb, first_group + i); + if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { + ext4_init_block_bitmap(sb, bh[i], + first_group + i, desc); + set_buffer_uptodate(bh[i]); + unlock_buffer(bh[i]); +- spin_unlock(sb_bgl_lock(EXT4_SB(sb), first_group + i)); ++ ext4_unlock_group(sb, first_group + i); + continue; + } +- spin_unlock(sb_bgl_lock(EXT4_SB(sb), first_group + i)); ++ ext4_unlock_group(sb, first_group + i); + get_bh(bh[i]); + bh[i]->b_end_io = end_buffer_read_sync; + submit_bh(READ, bh[i]); +@@ -1021,7 +1009,7 @@ static int mb_find_order_for_block(struc + return 0; + } + +-static void mb_clear_bits(spinlock_t *lock, void *bm, int cur, int len) ++static void mb_clear_bits(void *bm, int cur, int len) + { + __u32 *addr; + +@@ -1034,12 +1022,12 @@ static void mb_clear_bits(spinlock_t *lo + cur += 32; + continue; + } +- mb_clear_bit_atomic(lock, cur, bm); ++ mb_clear_bit(cur, bm); + cur++; + } + } + +-static void mb_set_bits(spinlock_t *lock, void *bm, int cur, int len) ++static void mb_set_bits(void *bm, int cur, int len) + { + __u32 *addr; + +@@ -1052,7 +1040,7 @@ static void mb_set_bits(spinlock_t *lock + cur += 32; + continue; + } +- mb_set_bit_atomic(lock, cur, bm); ++ mb_set_bit(cur, bm); + cur++; + } + } +@@ -1268,8 +1256,7 @@ static int mb_mark_used(struct ext4_budd + e4b->bd_info->bb_counters[ord]++; + } + +- mb_set_bits(sb_bgl_lock(EXT4_SB(e4b->bd_sb), ex->fe_group), +- EXT4_MB_BITMAP(e4b), ex->fe_start, len0); ++ mb_set_bits(EXT4_MB_BITMAP(e4b), ex->fe_start, len0); + mb_check_buddy(e4b); + + return ret; +@@ -2651,7 +2638,7 @@ int ext4_mb_init(struct super_block *sb, + return 0; + } + +-/* need to called with ext4 group lock (ext4_lock_group) */ ++/* need to called with the ext4 group lock held */ + static void ext4_mb_cleanup_pa(struct ext4_group_info *grp) + { + struct ext4_prealloc_space *pa; +@@ -3130,14 +3117,17 @@ ext4_mb_mark_diskspace_used(struct ext4_ + * Fix the bitmap and repeat the block allocation + * We leak some of the blocks here. + */ +- mb_set_bits(sb_bgl_lock(sbi, ac->ac_b_ex.fe_group), +- bitmap_bh->b_data, ac->ac_b_ex.fe_start, +- ac->ac_b_ex.fe_len); ++ ext4_lock_group(sb, ac->ac_b_ex.fe_group); ++ mb_set_bits(bitmap_bh->b_data, ac->ac_b_ex.fe_start, ++ ac->ac_b_ex.fe_len); ++ ext4_unlock_group(sb, ac->ac_b_ex.fe_group); + err = ext4_journal_dirty_metadata(handle, bitmap_bh); + if (!err) + err = -EAGAIN; + goto out_err; + } ++ ++ ext4_lock_group(sb, ac->ac_b_ex.fe_group); + #ifdef AGGRESSIVE_CHECK + { + int i; +@@ -3147,10 +3137,8 @@ ext4_mb_mark_diskspace_used(struct ext4_ + } + } + #endif +- mb_set_bits(sb_bgl_lock(sbi, ac->ac_b_ex.fe_group), bitmap_bh->b_data, +- ac->ac_b_ex.fe_start, ac->ac_b_ex.fe_len); ++ 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(EXT4_BG_BLOCK_UNINIT)) { + gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT); + gdp->bg_free_blocks_count = +@@ -3160,15 +3148,16 @@ ext4_mb_mark_diskspace_used(struct ext4_ + } + le16_add_cpu(&gdp->bg_free_blocks_count, -ac->ac_b_ex.fe_len); + gdp->bg_checksum = ext4_group_desc_csum(sbi, ac->ac_b_ex.fe_group, gdp); +- spin_unlock(sb_bgl_lock(sbi, ac->ac_b_ex.fe_group)); ++ ++ ext4_unlock_group(sb, ac->ac_b_ex.fe_group); + percpu_counter_sub(&sbi->s_freeblocks_counter, ac->ac_b_ex.fe_len); + + if (sbi->s_log_groups_per_flex) { + ext4_group_t flex_group = ext4_flex_group(sbi, + ac->ac_b_ex.fe_group); +- spin_lock(sb_bgl_lock(sbi, flex_group)); ++ ext4_lock_group(sb, flex_group); + sbi->s_flex_groups[flex_group].free_blocks -= ac->ac_b_ex.fe_len; +- spin_unlock(sb_bgl_lock(sbi, flex_group)); ++ ext4_unlock_group(sb, flex_group); + } + + err = ext4_journal_dirty_metadata(handle, bitmap_bh); +@@ -3600,7 +3589,7 @@ int ext4_mb_check_ondisk_bitmap(struct s + /* + * the function goes through all preallocation in this group and marks them + * used in in-core bitmap. buddy must be generated from this bitmap +- * Need to be called with ext4 group lock (ext4_lock_group) ++ * Need to be called with ext4 group lock held. + */ + static int ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap, + ext4_group_t group) +@@ -3646,8 +3635,7 @@ static int ext4_mb_generate_from_pa(stru + continue; + } + BUG_ON(groupnr != group); +- mb_set_bits(sb_bgl_lock(EXT4_SB(sb), group), +- bitmap, start, len); ++ mb_set_bits(bitmap, start, len); + preallocated += len; + count++; + } +@@ -4901,6 +4889,13 @@ do_more: + if (err) + goto error_return; + ++ if (ac) { ++ ac->ac_b_ex.fe_group = block_group; ++ ac->ac_b_ex.fe_start = bit; ++ ac->ac_b_ex.fe_len = count; ++ ext4_mb_store_history(ac); ++ } ++ + err = ext4_mb_load_buddy(sb, block_group, &e4b); + if (err) + goto error_return; +@@ -4912,42 +4907,31 @@ do_more: + BUG_ON(!mb_test_bit(bit + i, bitmap_bh->b_data)); + } + #endif +- mb_clear_bits(sb_bgl_lock(sbi, block_group), bitmap_bh->b_data, +- bit, count); +- ++ ext4_lock_group(sb, block_group); ++ mb_clear_bits(bitmap_bh->b_data, bit, count); + /* We dirtied the bitmap block */ + BUFFER_TRACE(bitmap_bh, "dirtied bitmap block"); + err = ext4_journal_dirty_metadata(handle, bitmap_bh); + +- if (ac) { +- ac->ac_b_ex.fe_group = block_group; +- ac->ac_b_ex.fe_start = bit; +- ac->ac_b_ex.fe_len = count; +- ext4_mb_store_history(ac); +- } +- + if (metadata) { + /* blocks being freed are metadata. these blocks shouldn't + * be used until this transaction is committed */ + ext4_mb_free_metadata(handle, &e4b, block_group, bit, count); + } else { +- ext4_lock_group(sb, block_group); + mb_free_blocks(inode, &e4b, bit, count); + ext4_mb_return_to_preallocation(inode, &e4b, block, count); +- ext4_unlock_group(sb, block_group); + } + +- spin_lock(sb_bgl_lock(sbi, block_group)); + le16_add_cpu(&gdp->bg_free_blocks_count, count); + gdp->bg_checksum = ext4_group_desc_csum(sbi, block_group, gdp); +- spin_unlock(sb_bgl_lock(sbi, block_group)); ++ ext4_unlock_group(sb, block_group); + percpu_counter_add(&sbi->s_freeblocks_counter, count); + + if (sbi->s_log_groups_per_flex) { + ext4_group_t flex_group = ext4_flex_group(sbi, block_group); +- spin_lock(sb_bgl_lock(sbi, flex_group)); ++ ext4_lock_group(sb, flex_group); + sbi->s_flex_groups[flex_group].free_blocks += count; +- spin_unlock(sb_bgl_lock(sbi, flex_group)); ++ ext4_unlock_group(sb, flex_group); + } + + ext4_mb_release_desc(&e4b); +Index: linux-2.6.18-128.1.6/fs/ext4/super.c +=================================================================== +--- linux-2.6.18-128.1.6.orig/fs/ext4/super.c ++++ linux-2.6.18-128.1.6/fs/ext4/super.c +@@ -1934,16 +1934,18 @@ static int ext4_check_descriptors(struct + "(block %llu)!", i, inode_table); + return 0; + } +- spin_lock(sb_bgl_lock(sbi, i)); ++ ext4_lock_group(sb, i); + if (!ext4_group_desc_csum_verify(sbi, i, gdp)) { + printk(KERN_ERR "EXT4-fs: ext4_check_descriptors: " + "Checksum for group %lu failed (%u!=%u)\n", + i, le16_to_cpu(ext4_group_desc_csum(sbi, i, + gdp)), le16_to_cpu(gdp->bg_checksum)); +- if (!(sb->s_flags & MS_RDONLY)) ++ if (!(sb->s_flags & MS_RDONLY)) { ++ ext4_unlock_group(sb, i); + return 0; ++ } + } +- spin_unlock(sb_bgl_lock(sbi, i)); ++ ext4_unlock_group(sb, i); + if (!flexbg_flag) + first_block += EXT4_BLOCKS_PER_GROUP(sb); + } +Index: linux-2.6.18-128.1.6/fs/ext4/ext4.h +=================================================================== +--- linux-2.6.18-128.1.6.orig/fs/ext4/ext4.h ++++ linux-2.6.18-128.1.6/fs/ext4/ext4.h +@@ -1303,6 +1303,33 @@ extern int ext4_get_blocks_wrap(handle_t + sector_t block, unsigned long max_blocks, + struct buffer_head *bh, int create, + int extend_disksize); ++ ++static inline spinlock_t *ext4_group_lock_ptr(struct super_block *sb, ++ ext4_group_t group) ++{ ++ struct blockgroup_lock *bgl = &EXT4_SB(sb)->s_blockgroup_lock; ++ return &bgl->locks[group & (NR_BG_LOCKS-1)].lock; ++} ++ ++static inline void ext4_lock_group(struct super_block *sb, ext4_group_t group) ++{ ++ spin_lock(ext4_group_lock_ptr(sb, group)); ++} ++ ++static inline void ext4_unlock_group(struct super_block *sb, ++ ext4_group_t group) ++{ ++ spin_unlock(ext4_group_lock_ptr(sb, group)); ++} ++ ++static inline int ext4_is_group_locked(struct super_block *sb, ++ ext4_group_t group) ++{ ++ return spin_is_locked(ext4_group_lock_ptr(sb, group)); ++} ++ ++ ++ + #endif /* __KERNEL__ */ + + #endif /* _EXT4_H */ +Index: linux-2.6.18-128.1.6/fs/ext4/mballoc.h +=================================================================== +--- linux-2.6.18-128.1.6.orig/fs/ext4/mballoc.h ++++ linux-2.6.18-128.1.6/fs/ext4/mballoc.h +@@ -126,7 +126,6 @@ struct ext4_group_info { + }; + + #define EXT4_GROUP_INFO_NEED_INIT_BIT 0 +-#define EXT4_GROUP_INFO_LOCKED_BIT 1 + + #define EXT4_MB_GRP_NEED_INIT(grp) \ + (test_bit(EXT4_GROUP_INFO_NEED_INIT_BIT, &((grp)->bb_state))) +@@ -272,31 +271,6 @@ static void ext4_mb_put_pa(struct ext4_a + static int ext4_mb_init_per_dev_proc(struct super_block *sb); + static int ext4_mb_destroy_per_dev_proc(struct super_block *sb); + +- +-static inline void ext4_lock_group(struct super_block *sb, ext4_group_t group) +-{ +- struct ext4_group_info *grinfo = ext4_get_group_info(sb, group); +- +- bit_spin_lock(EXT4_GROUP_INFO_LOCKED_BIT, &(grinfo->bb_state)); +-} +- +-static inline void ext4_unlock_group(struct super_block *sb, +- ext4_group_t group) +-{ +- struct ext4_group_info *grinfo = ext4_get_group_info(sb, group); +- +- bit_spin_unlock(EXT4_GROUP_INFO_LOCKED_BIT, &(grinfo->bb_state)); +-} +- +-static inline int ext4_is_group_locked(struct super_block *sb, +- ext4_group_t group) +-{ +- struct ext4_group_info *grinfo = ext4_get_group_info(sb, group); +- +- return bit_spin_is_locked(EXT4_GROUP_INFO_LOCKED_BIT, +- &(grinfo->bb_state)); +-} +- + static ext4_fsblk_t ext4_grp_offs_to_block(struct super_block *sb, + struct ext4_free_extent *fex) + { diff --git a/ldiskfs/kernel_patches/patches/ext4-mballoc-extra-checks-rhel5.patch b/ldiskfs/kernel_patches/patches/ext4-mballoc-extra-checks-rhel5.patch index b8cdada..7a77781 100644 --- a/ldiskfs/kernel_patches/patches/ext4-mballoc-extra-checks-rhel5.patch +++ b/ldiskfs/kernel_patches/patches/ext4-mballoc-extra-checks-rhel5.patch @@ -1,7 +1,7 @@ -Index: linux-2.6.18.i686/fs/ext4/mballoc.c +Index: linux-2.6.18-128.1.6/fs/ext4/mballoc.c =================================================================== ---- linux-2.6.18.i686.orig/fs/ext4/mballoc.c -+++ linux-2.6.18.i686/fs/ext4/mballoc.c +--- linux-2.6.18-128.1.6.orig/fs/ext4/mballoc.c ++++ linux-2.6.18-128.1.6/fs/ext4/mballoc.c @@ -660,7 +660,7 @@ static void ext4_mb_mark_free_simple(str } } @@ -145,13 +145,14 @@ Index: linux-2.6.18.i686/fs/ext4/mballoc.c if (ac->ac_op == EXT4_MB_HISTORY_ALLOC) { if (ac->ac_g_ex.fe_start == ac->ac_b_ex.fe_start && ac->ac_g_ex.fe_group == ac->ac_b_ex.fe_group) -@@ -3531,22 +3547,66 @@ ext4_mb_use_preallocated(struct ext4_all +@@ -3539,22 +3555,67 @@ ext4_mb_use_preallocated(struct ext4_all } /* + * check free blocks in bitmap match free block in group descriptor + * do this before taking preallocated blocks into account to be able -+ * to detect on-disk corruptions ++ * to detect on-disk corruptions. The group lock should be hold by the ++ * caller. + */ +int ext4_mb_check_ondisk_bitmap(struct super_block *sb, void *bitmap, + struct ext4_group_desc *gdp, int group) @@ -163,7 +164,7 @@ Index: linux-2.6.18.i686/fs/ext4/mballoc.c + + while (i < max) { + first = i; -+ i = find_next_bit(bitmap, max, i); ++ i = mb_find_next_bit(bitmap, max, i); + if (i > max) + i = max; + free += i - first; @@ -213,7 +214,7 @@ Index: linux-2.6.18.i686/fs/ext4/mballoc.c /* all form of preallocation discards first load group, * so the only competing code is preallocation use. * we don't need any locking here -@@ -3562,15 +3622,24 @@ static void ext4_mb_generate_from_pa(str +@@ -3570,15 +3631,24 @@ static void ext4_mb_generate_from_pa(str &groupnr, &start); len = pa->pa_len; spin_unlock(&pa->pa_lock); @@ -239,7 +240,7 @@ Index: linux-2.6.18.i686/fs/ext4/mballoc.c } static void ext4_mb_pa_callback(struct rcu_head *head) -@@ -3621,6 +3690,7 @@ static void ext4_mb_put_pa(struct ext4_a +@@ -3629,6 +3699,7 @@ static void ext4_mb_put_pa(struct ext4_a */ ext4_lock_group(sb, grp); list_del(&pa->pa_group_list); @@ -247,7 +248,7 @@ Index: linux-2.6.18.i686/fs/ext4/mballoc.c ext4_unlock_group(sb, grp); spin_lock(pa->pa_obj_lock); -@@ -3709,6 +3779,7 @@ ext4_mb_new_inode_pa(struct ext4_allocat +@@ -3717,6 +3788,7 @@ ext4_mb_new_inode_pa(struct ext4_allocat ext4_lock_group(sb, ac->ac_b_ex.fe_group); list_add(&pa->pa_group_list, &grp->bb_prealloc_list); @@ -255,7 +256,7 @@ Index: linux-2.6.18.i686/fs/ext4/mballoc.c ext4_unlock_group(sb, ac->ac_b_ex.fe_group); spin_lock(pa->pa_obj_lock); -@@ -3768,6 +3839,7 @@ ext4_mb_new_group_pa(struct ext4_allocat +@@ -3776,6 +3848,7 @@ ext4_mb_new_group_pa(struct ext4_allocat ext4_lock_group(sb, ac->ac_b_ex.fe_group); list_add(&pa->pa_group_list, &grp->bb_prealloc_list); @@ -263,7 +264,7 @@ Index: linux-2.6.18.i686/fs/ext4/mballoc.c ext4_unlock_group(sb, ac->ac_b_ex.fe_group); /* -@@ -3820,6 +3892,7 @@ ext4_mb_release_inode_pa(struct ext4_bud +@@ -3828,6 +3901,7 @@ ext4_mb_release_inode_pa(struct ext4_bud ac->ac_sb = sb; ac->ac_inode = pa->pa_inode; ac->ac_op = EXT4_MB_HISTORY_DISCARD; @@ -271,7 +272,7 @@ Index: linux-2.6.18.i686/fs/ext4/mballoc.c } while (bit < end) { -@@ -3964,6 +4037,8 @@ repeat: +@@ -3972,6 +4046,8 @@ repeat: spin_unlock(&pa->pa_lock); @@ -280,7 +281,7 @@ Index: linux-2.6.18.i686/fs/ext4/mballoc.c list_del(&pa->pa_group_list); list_add(&pa->u.pa_tmp_list, &list); } -@@ -4099,7 +4174,7 @@ repeat: +@@ -4107,7 +4183,7 @@ repeat: if (err) { ext4_error(sb, __func__, "Error in loading buddy " "information for %lu\n", group); @@ -289,7 +290,7 @@ Index: linux-2.6.18.i686/fs/ext4/mballoc.c } bitmap_bh = ext4_read_block_bitmap(sb, group); -@@ -4111,6 +4186,8 @@ repeat: +@@ -4119,6 +4195,8 @@ repeat: } ext4_lock_group(sb, group); @@ -298,10 +299,10 @@ Index: linux-2.6.18.i686/fs/ext4/mballoc.c list_del(&pa->pa_group_list); ext4_mb_release_inode_pa(&e4b, bitmap_bh, pa, ac); ext4_unlock_group(sb, group); -Index: linux-2.6.18.i686/fs/ext4/mballoc.h +Index: linux-2.6.18-128.1.6/fs/ext4/mballoc.h =================================================================== ---- linux-2.6.18.i686.orig/fs/ext4/mballoc.h -+++ linux-2.6.18.i686/fs/ext4/mballoc.h +--- linux-2.6.18-128.1.6.orig/fs/ext4/mballoc.h ++++ linux-2.6.18-128.1.6/fs/ext4/mballoc.h @@ -119,6 +119,7 @@ struct ext4_group_info { unsigned short bb_free; unsigned short bb_fragments; diff --git a/ldiskfs/kernel_patches/series/ldiskfs-2.6-rhel5-ext4.series b/ldiskfs/kernel_patches/series/ldiskfs-2.6-rhel5-ext4.series index 240979e..294e9b2 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-2.6-rhel5-ext4.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-2.6-rhel5-ext4.series @@ -19,3 +19,4 @@ ext4-mballoc-handle-dev-paths-rhel5.patch ext4-big-endian-check-2.6-rhel5.patch ext4-alloc-policy-2.6-rhel5.patch ext4-misc-rhel5.patch +ext4-convert-group-lock-rhel5.patch -- 1.8.3.1