From d87d9b1957584d6e9885f527082f84c5f4efb9dc Mon Sep 17 00:00:00 2001 From: Andrew Perepechko Date: Mon, 6 Sep 2010 19:34:04 +0400 Subject: [PATCH] Revert "b=22117 Patch to limit mmp interval." This reverts commit 0791b46099339efcf608ff99822be01766f90656. --- .../patches/ext3-mmp-2.6-sles10.patch | 65 ++++------- .../patches/ext3-mmp-2.6.18-vanilla.patch | 89 ++++++--------- .../kernel_patches/patches/ext4-mmp-rhel5.patch | 115 ++++++++----------- .../kernel_patches/patches/ext4-mmp-sles11.patch | 124 +++++++++------------ 4 files changed, 160 insertions(+), 233 deletions(-) diff --git a/ldiskfs/kernel_patches/patches/ext3-mmp-2.6-sles10.patch b/ldiskfs/kernel_patches/patches/ext3-mmp-2.6-sles10.patch index 239d1e1..0a4f9db 100644 --- a/ldiskfs/kernel_patches/patches/ext3-mmp-2.6-sles10.patch +++ b/ldiskfs/kernel_patches/patches/ext3-mmp-2.6-sles10.patch @@ -65,7 +65,7 @@ Index: linux-stage/fs/ext3/super.c jbd_debug(2, "deleting unreferenced inode %ld\n", inode->i_ino); nr_orphans++; -@@ -1525,6 +1529,351 @@ static unsigned long descriptor_loc(stru +@@ -1525,6 +1529,346 @@ static unsigned long descriptor_loc(stru return (first_data_block + has_super + (bg * sbi->s_blocks_per_group)); } @@ -149,9 +149,9 @@ Index: linux-stage/fs/ext3/super.c + */ +static int kmmpd(void *data) +{ -+ struct super_block *sb = ((struct mmpd_data *) data)->sb; -+ struct buffer_head *bh = ((struct mmpd_data *) data)->bh; ++ struct super_block *sb = (struct super_block *) data; + struct ext3_super_block *es = EXT3_SB(sb)->s_es; ++ struct buffer_head *bh = NULL; + struct mmp_struct *mmp; + unsigned long mmp_block; + u32 seq = 0; @@ -163,13 +163,17 @@ Index: linux-stage/fs/ext3/super.c + int retval; + + mmp_block = le64_to_cpu(es->s_mmp_block); ++ retval = read_mmp_block(sb, &bh, mmp_block); ++ if (retval) ++ goto failed; ++ + mmp = (struct mmp_struct *)(bh->b_data); + mmp->mmp_time = cpu_to_le64(get_seconds()); + /* + * Start with the higher mmp_check_interval and reduce it if + * the MMP block is being updated on time. + */ -+ mmp_check_interval = max(5UL * mmp_update_interval, ++ mmp_check_interval = max(5 * mmp_update_interval, + EXT3_MMP_MIN_CHECK_INTERVAL); + mmp->mmp_check_interval = cpu_to_le16(mmp_check_interval); + bdevname(bh->b_bdev, mmp->mmp_bdevname); @@ -251,9 +255,8 @@ Index: linux-stage/fs/ext3/super.c + * Adjust the mmp_check_interval depending on how much time + * it took for the MMP block to be written. + */ -+ mmp_check_interval = max(min(5 * diff / HZ, -+ EXT3_MMP_MAX_CHECK_INTERVAL), -+ EXT3_MMP_MIN_CHECK_INTERVAL); ++ mmp_check_interval = max(5 * diff / HZ, ++ (unsigned long) EXT3_MMP_MIN_CHECK_INTERVAL); + mmp->mmp_check_interval = cpu_to_le16(mmp_check_interval); + } + @@ -294,7 +297,6 @@ Index: linux-stage/fs/ext3/super.c + struct ext3_super_block *es = EXT3_SB(sb)->s_es; + struct buffer_head *bh = NULL; + struct mmp_struct *mmp = NULL; -+ struct mmpd_data *mmpd_data; + u32 seq; + unsigned int mmp_check_interval = le16_to_cpu(es->s_mmp_update_interval); + unsigned int wait_time = 0; @@ -386,20 +388,12 @@ Index: linux-stage/fs/ext3/super.c + goto failed; + } + -+ mmpd_data = kmalloc(sizeof(struct mmpd_data *), GFP_KERNEL); -+ if (!mmpd_data) { -+ ext3_warning(sb, KERN_ERR, "not enough memory for mmpd_data"); -+ goto failed; -+ } -+ mmpd_data->sb = sb; -+ mmpd_data->bh = bh; -+ + /* + * Start a kernel thread to update the MMP block periodically. + */ -+ EXT3_SB(sb)->s_mmp_tsk = kthread_run(kmmpd, mmpd_data, "kmmpd-%s", -+ bdevname(bh->b_bdev, -+ mmp->mmp_bdevname)); ++ EXT3_SB(sb)->s_mmp_tsk = kthread_run(kmmpd, sb, "kmmpd-%02x:%02x", ++ MAJOR(sb->s_dev), ++ MINOR(sb->s_dev)); + if (IS_ERR(EXT3_SB(sb)->s_mmp_tsk)) { + EXT3_SB(sb)->s_mmp_tsk = 0; + ext3_warning(sb, __func__, "Unable to create kmmpd thread " @@ -407,6 +401,7 @@ Index: linux-stage/fs/ext3/super.c + goto failed; + } + ++ brelse(bh); + return 0; + +failed: @@ -417,7 +412,7 @@ Index: linux-stage/fs/ext3/super.c static int ext3_fill_super (struct super_block *sb, void *data, int silent) { -@@ -1848,6 +2197,11 @@ static int ext3_fill_super (struct super +@@ -1848,6 +2192,11 @@ static int ext3_fill_super (struct super EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER)); @@ -429,7 +424,7 @@ Index: linux-stage/fs/ext3/super.c /* * The first inode we look at is the journal inode. Don't try * root first: it may be modified in the journal! -@@ -1992,6 +2346,8 @@ cantfind_ext3: +@@ -1992,6 +2341,8 @@ cantfind_ext3: failed_mount3: journal_destroy(sbi->s_journal); failed_mount2: @@ -438,7 +433,7 @@ Index: linux-stage/fs/ext3/super.c for (i = 0; i < db_count; i++) brelse(sbi->s_group_desc[i]); kfree(sbi->s_group_desc); -@@ -2357,9 +2713,9 @@ static void ext3_clear_journal_err(struc +@@ -2357,9 +2708,9 @@ static void ext3_clear_journal_err(struc char nbuf[16]; errstr = ext3_decode_error(sb, j_errno, nbuf); @@ -450,7 +445,7 @@ Index: linux-stage/fs/ext3/super.c "filesystem check."); EXT3_SB(sb)->s_mount_state |= EXT3_ERROR_FS; -@@ -2462,7 +2818,7 @@ static int ext3_remount (struct super_bl +@@ -2462,7 +2813,7 @@ static int ext3_remount (struct super_bl unsigned long n_blocks_count = 0; unsigned long old_sb_flags; struct ext3_mount_options old_opts; @@ -459,7 +454,7 @@ Index: linux-stage/fs/ext3/super.c #ifdef CONFIG_QUOTA int i; #endif -@@ -2488,7 +2844,7 @@ static int ext3_remount (struct super_bl +@@ -2488,7 +2839,7 @@ static int ext3_remount (struct super_bl } if (sbi->s_mount_opt & EXT3_MOUNT_ABORT) @@ -468,7 +463,7 @@ Index: linux-stage/fs/ext3/super.c sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | ((sbi->s_mount_opt & EXT3_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0); -@@ -2546,6 +2902,13 @@ static int ext3_remount (struct super_bl +@@ -2546,6 +2897,13 @@ static int ext3_remount (struct super_bl } if (!ext3_setup_super (sb, es, 0)) sb->s_flags &= ~MS_RDONLY; @@ -523,7 +518,7 @@ Index: linux-stage/include/linux/ext3_fs.h #define EXT3_FEATURE_RO_COMPAT_SUPP (EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER| \ EXT3_FEATURE_RO_COMPAT_LARGE_FILE| \ EXT4_FEATURE_RO_COMPAT_GDT_CSUM| \ -@@ -862,6 +868,50 @@ struct dir_private_info { +@@ -862,6 +868,39 @@ struct dir_private_info { #define ERR_BAD_DX_DIR -75000 /* @@ -549,12 +544,6 @@ Index: linux-stage/include/linux/ext3_fs.h + __le32 mmp_pad2[227]; +}; + -+/* arguments passed to the mmp thread */ -+struct mmpd_data { -+ struct buffer_head *bh; /* bh from initial read_mmp_block() */ -+ struct super_block *sb; /* super block of the fs */ -+}; -+ +/* + * Default interval in seconds to update the MMP sequence number. + */ @@ -563,12 +552,7 @@ Index: linux-stage/include/linux/ext3_fs.h +/* + * Minimum interval for MMP checking in seconds. + */ -+#define EXT3_MMP_MIN_CHECK_INTERVAL 5UL -+ -+/* -+ * Maximum interval for MMP checking in seconds. -+ */ -+#define EXT3_MMP_MAX_CHECK_INTERVAL 300UL ++#define EXT3_MMP_MIN_CHECK_INTERVAL 5 + +/* * Function prototypes @@ -578,12 +562,11 @@ Index: linux-stage/include/linux/ext3_fs_sb.h =================================================================== --- linux-stage.orig/include/linux/ext3_fs_sb.h +++ linux-stage/include/linux/ext3_fs_sb.h -@@ -145,6 +145,8 @@ struct ext3_sb_info { +@@ -145,6 +145,7 @@ struct ext3_sb_info { /* locality groups */ struct ext3_locality_group *s_locality_groups; -+ /* Kernel thread for multiple mount protection */ -+ struct task_struct *s_mmp_tsk; ++ struct task_struct *s_mmp_tsk; /* Kernel thread for multiple mount protection */ }; #define EXT3_GROUP_INFO(sb, group) \ diff --git a/ldiskfs/kernel_patches/patches/ext3-mmp-2.6.18-vanilla.patch b/ldiskfs/kernel_patches/patches/ext3-mmp-2.6.18-vanilla.patch index 0ee6718..c608907 100644 --- a/ldiskfs/kernel_patches/patches/ext3-mmp-2.6.18-vanilla.patch +++ b/ldiskfs/kernel_patches/patches/ext3-mmp-2.6.18-vanilla.patch @@ -38,7 +38,7 @@ Index: linux-stage/fs/ext3/super.c if (sbi->s_dev_proc) { remove_proc_entry(sbi->s_dev_proc->name, proc_root_ext3); sbi->s_dev_proc = NULL; -@@ -1395,7 +1399,7 @@ static int ext3_check_descriptors (struc +@@ -1375,7 +1379,7 @@ static int ext3_check_descriptors (struc return 0; } if (!ext3_group_desc_csum_verify(sbi, i, gdp)) { @@ -47,7 +47,7 @@ Index: linux-stage/fs/ext3/super.c "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)); -@@ -1490,7 +1494,7 @@ static void ext3_orphan_cleanup (struct +@@ -1470,7 +1474,7 @@ static void ext3_orphan_cleanup (struct if (inode->i_nlink) { printk(KERN_DEBUG "%s: truncating inode %lu to %Ld bytes\n", @@ -56,7 +56,7 @@ Index: linux-stage/fs/ext3/super.c jbd_debug(2, "truncating inode %lu to %Ld bytes\n", inode->i_ino, inode->i_size); ext3_truncate(inode); -@@ -1498,7 +1502,7 @@ static void ext3_orphan_cleanup (struct +@@ -1478,7 +1482,7 @@ static void ext3_orphan_cleanup (struct } else { printk(KERN_DEBUG "%s: deleting unreferenced inode %lu\n", @@ -65,7 +65,7 @@ Index: linux-stage/fs/ext3/super.c jbd_debug(2, "deleting unreferenced inode %lu\n", inode->i_ino); nr_orphans++; -@@ -1568,6 +1572,355 @@ static ext3_fsblk_t descriptor_loc(struc +@@ -1548,6 +1552,346 @@ static ext3_fsblk_t descriptor_loc(struc return (has_super + ext3_group_first_block_no(sb, bg)); } @@ -149,9 +149,9 @@ Index: linux-stage/fs/ext3/super.c + */ +static int kmmpd(void *data) +{ -+ struct super_block *sb = ((struct mmpd_data *) data)->sb; -+ struct buffer_head *bh = ((struct mmpd_data *) data)->bh; ++ struct super_block *sb = (struct super_block *) data; + struct ext3_super_block *es = EXT3_SB(sb)->s_es; ++ struct buffer_head *bh = NULL; + struct mmp_struct *mmp; + unsigned long mmp_block; + u32 seq = 0; @@ -163,13 +163,17 @@ Index: linux-stage/fs/ext3/super.c + int retval; + + mmp_block = le64_to_cpu(es->s_mmp_block); ++ retval = read_mmp_block(sb, &bh, mmp_block); ++ if (retval) ++ goto failed; ++ + mmp = (struct mmp_struct *)(bh->b_data); + mmp->mmp_time = cpu_to_le64(get_seconds()); + /* + * Start with the higher mmp_check_interval and reduce it if + * the MMP block is being updated on time. + */ -+ mmp_check_interval = max(5UL * mmp_update_interval, ++ mmp_check_interval = max(5 * mmp_update_interval, + EXT3_MMP_MIN_CHECK_INTERVAL); + mmp->mmp_check_interval = cpu_to_le16(mmp_check_interval); + bdevname(bh->b_bdev, mmp->mmp_bdevname); @@ -202,7 +206,7 @@ Index: linux-stage/fs/ext3/super.c + EXT3_FEATURE_INCOMPAT_MMP)) { + ext3_warning(sb, __func__, "kmmpd being stopped " + "since MMP feature has been disabled."); -+ EXT3_SB(sb)->s_mmp_tsk = NULL; ++ EXT3_SB(sb)->s_mmp_tsk = 0; + goto failed; + } + @@ -210,7 +214,7 @@ Index: linux-stage/fs/ext3/super.c + ext3_warning(sb, __func__, "kmmpd being stopped " + "since filesystem has been remounted as " + "readonly."); -+ EXT3_SB(sb)->s_mmp_tsk = NULL; ++ EXT3_SB(sb)->s_mmp_tsk = 0; + goto failed; + } + @@ -231,23 +235,19 @@ Index: linux-stage/fs/ext3/super.c + + retval = read_mmp_block(sb, &bh_check, mmp_block); + if (retval) { -+ ext3_error(sb, __func__, "error reading MMP" -+ "data: %d", retval); -+ EXT3_SB(sb)->s_mmp_tsk = NULL; ++ EXT3_SB(sb)->s_mmp_tsk = 0; + goto failed; + } + + mmp_check = (struct mmp_struct *)(bh_check->b_data); -+ if (mmp->mmp_seq != mmp_check->mmp_seq || ++ if (mmp->mmp_time != mmp_check->mmp_time || + memcmp(mmp->mmp_nodename, mmp_check->mmp_nodename, -+ sizeof(mmp->mmp_nodename))) { ++ sizeof(mmp->mmp_nodename))) + dump_mmp_msg(sb, mmp_check, __func__, + "Error while updating MMP info. " + "The filesystem seems to have " + "been multiply mounted."); -+ ext3_error(sb, __func__, "abort"); -+ goto failed; -+ } ++ + put_bh(bh_check); + } + @@ -255,9 +255,8 @@ Index: linux-stage/fs/ext3/super.c + * Adjust the mmp_check_interval depending on how much time + * it took for the MMP block to be written. + */ -+ mmp_check_interval = max(min(5 * diff / HZ, -+ EXT3_MMP_MAX_CHECK_INTERVAL), -+ EXT3_MMP_MIN_CHECK_INTERVAL); ++ mmp_check_interval = max(5 * diff / HZ, ++ (unsigned long) EXT3_MMP_MIN_CHECK_INTERVAL); + mmp->mmp_check_interval = cpu_to_le16(mmp_check_interval); + } + @@ -298,7 +297,6 @@ Index: linux-stage/fs/ext3/super.c + struct ext3_super_block *es = EXT3_SB(sb)->s_es; + struct buffer_head *bh = NULL; + struct mmp_struct *mmp = NULL; -+ struct mmpd_data *mmpd_data; + u32 seq; + unsigned int mmp_check_interval = le16_to_cpu(es->s_mmp_update_interval); + unsigned int wait_time = 0; @@ -390,27 +388,20 @@ Index: linux-stage/fs/ext3/super.c + goto failed; + } + -+ mmpd_data = kmalloc(sizeof(struct mmpd_data *), GFP_KERNEL); -+ if (!mmpd_data) { -+ ext3_warning(sb, KERN_ERR, "not enough memory for mmpd_data"); -+ goto failed; -+ } -+ mmpd_data->sb = sb; -+ mmpd_data->bh = bh; -+ + /* + * Start a kernel thread to update the MMP block periodically. + */ -+ EXT3_SB(sb)->s_mmp_tsk = kthread_run(kmmpd, mmpd_data, "kmmpd-%s", -+ bdevname(bh->b_bdev, -+ mmp->mmp_bdevname)); ++ EXT3_SB(sb)->s_mmp_tsk = kthread_run(kmmpd, sb, "kmmpd-%02x:%02x", ++ MAJOR(sb->s_dev), ++ MINOR(sb->s_dev)); + if (IS_ERR(EXT3_SB(sb)->s_mmp_tsk)) { -+ EXT3_SB(sb)->s_mmp_tsk = NULL; ++ EXT3_SB(sb)->s_mmp_tsk = 0; + ext3_warning(sb, __func__, "Unable to create kmmpd thread " + "for %s.", sb->s_id); + goto failed; + } + ++ brelse(bh); + return 0; + +failed: @@ -421,7 +412,7 @@ Index: linux-stage/fs/ext3/super.c static int ext3_fill_super (struct super_block *sb, void *data, int silent) { -@@ -1901,6 +2254,11 @@ static int ext3_fill_super (struct super +@@ -1880,6 +2224,11 @@ static int ext3_fill_super (struct super EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER)); @@ -433,7 +424,7 @@ Index: linux-stage/fs/ext3/super.c /* * The first inode we look at is the journal inode. Don't try * root first: it may be modified in the journal! -@@ -2033,6 +2391,8 @@ cantfind_ext3: +@@ -2012,6 +2361,8 @@ cantfind_ext3: failed_mount4: journal_destroy(sbi->s_journal); failed_mount3: @@ -442,7 +433,7 @@ Index: linux-stage/fs/ext3/super.c percpu_counter_destroy(&sbi->s_freeblocks_counter); percpu_counter_destroy(&sbi->s_freeinodes_counter); percpu_counter_destroy(&sbi->s_dirs_counter); -@@ -2409,9 +2769,9 @@ static void ext3_clear_journal_err(struc +@@ -2388,9 +2739,9 @@ static void ext3_clear_journal_err(struc char nbuf[16]; errstr = ext3_decode_error(sb, j_errno, nbuf); @@ -454,7 +445,7 @@ Index: linux-stage/fs/ext3/super.c "filesystem check."); EXT3_SB(sb)->s_mount_state |= EXT3_ERROR_FS; -@@ -2531,7 +2891,7 @@ static int ext3_remount (struct super_bl +@@ -2510,7 +2861,7 @@ static int ext3_remount (struct super_bl ext3_fsblk_t n_blocks_count = 0; unsigned long old_sb_flags; struct ext3_mount_options old_opts; @@ -463,7 +454,7 @@ Index: linux-stage/fs/ext3/super.c #ifdef CONFIG_QUOTA int i; #endif -@@ -2557,7 +2917,7 @@ static int ext3_remount (struct super_bl +@@ -2536,7 +2887,7 @@ static int ext3_remount (struct super_bl } if (sbi->s_mount_opt & EXT3_MOUNT_ABORT) @@ -472,7 +463,7 @@ Index: linux-stage/fs/ext3/super.c sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | ((sbi->s_mount_opt & EXT3_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0); -@@ -2630,6 +2990,13 @@ static int ext3_remount (struct super_bl +@@ -2609,6 +2960,13 @@ static int ext3_remount (struct super_bl } if (!ext3_setup_super (sb, es, 0)) sb->s_flags &= ~MS_RDONLY; @@ -527,7 +518,7 @@ Index: linux-stage/include/linux/ext3_fs.h #define EXT3_FEATURE_RO_COMPAT_SUPP (EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER| \ EXT3_FEATURE_RO_COMPAT_LARGE_FILE| \ EXT4_FEATURE_RO_COMPAT_GDT_CSUM| \ -@@ -871,6 +877,50 @@ ext3_group_first_block_no(struct super_b +@@ -871,6 +877,39 @@ ext3_group_first_block_no(struct super_b #define ERR_BAD_DX_DIR -75000 /* @@ -553,12 +544,6 @@ Index: linux-stage/include/linux/ext3_fs.h + __le32 mmp_pad2[227]; +}; + -+/* arguments passed to the mmp thread */ -+struct mmpd_data { -+ struct buffer_head *bh; /* bh from initial read_mmp_block() */ -+ struct super_block *sb; /* super block of the fs */ -+}; -+ +/* + * Default interval in seconds to update the MMP sequence number. + */ @@ -567,12 +552,7 @@ Index: linux-stage/include/linux/ext3_fs.h +/* + * Minimum interval for MMP checking in seconds. + */ -+#define EXT3_MMP_MIN_CHECK_INTERVAL 5UL -+ -+/* -+ * Maximum interval for MMP checking in seconds. -+ */ -+#define EXT3_MMP_MAX_CHECK_INTERVAL 300UL ++#define EXT3_MMP_MIN_CHECK_INTERVAL 5 + +/* * Function prototypes @@ -582,12 +562,11 @@ Index: linux-stage/include/linux/ext3_fs_sb.h =================================================================== --- linux-stage.orig/include/linux/ext3_fs_sb.h +++ linux-stage/include/linux/ext3_fs_sb.h -@@ -157,6 +157,8 @@ struct ext3_sb_info { +@@ -156,6 +156,7 @@ struct ext3_sb_info { /* locality groups */ struct ext3_locality_group *s_locality_groups; -+ /* Kernel thread for multiple mount protection */ -+ struct task_struct *s_mmp_tsk; ++ struct task_struct *s_mmp_tsk; /* Kernel thread for multiple mount protection */ }; #define EXT3_GROUP_INFO(sb, group) \ diff --git a/ldiskfs/kernel_patches/patches/ext4-mmp-rhel5.patch b/ldiskfs/kernel_patches/patches/ext4-mmp-rhel5.patch index 7bd8c7c..626c37c 100644 --- a/ldiskfs/kernel_patches/patches/ext4-mmp-rhel5.patch +++ b/ldiskfs/kernel_patches/patches/ext4-mmp-rhel5.patch @@ -2,7 +2,7 @@ Index: linux-stage/fs/ext4/super.c =================================================================== --- linux-stage.orig/fs/ext4/super.c +++ linux-stage/fs/ext4/super.c -@@ -40,6 +40,8 @@ +@@ -38,6 +38,8 @@ #include #include #include @@ -11,16 +11,16 @@ Index: linux-stage/fs/ext4/super.c #include "ext4.h" #include "ext4_jbd2.h" -@@ -660,6 +662,8 @@ static void ext4_put_super(struct super_ +@@ -617,6 +619,8 @@ static void ext4_put_super(struct super_ invalidate_bdev(sbi->journal_bdev, 0); ext4_blkdev_remove(sbi); } + if (sbi->s_mmp_tsk) + kthread_stop(sbi->s_mmp_tsk); sb->s_fs_info = NULL; - /* - * Now that we are completely done shutting down the -@@ -921,6 +925,354 @@ static int ext4_show_options(struct seq_ + kfree(sbi); + return; +@@ -864,6 +868,345 @@ static int ext4_show_options(struct seq_ return 0; } @@ -104,9 +104,9 @@ Index: linux-stage/fs/ext4/super.c + */ +static int kmmpd(void *data) +{ -+ struct super_block *sb = ((struct mmpd_data *) data)->sb; -+ struct buffer_head *bh = ((struct mmpd_data *) data)->bh; ++ struct super_block *sb = (struct super_block *) data; + struct ext4_super_block *es = EXT4_SB(sb)->s_es; ++ struct buffer_head *bh = NULL; + struct mmp_struct *mmp; + unsigned long mmp_block; + u32 seq = 0; @@ -118,13 +118,17 @@ Index: linux-stage/fs/ext4/super.c + int retval; + + mmp_block = le64_to_cpu(es->s_mmp_block); ++ retval = read_mmp_block(sb, &bh, mmp_block); ++ if (retval) ++ goto failed; ++ + mmp = (struct mmp_struct *)(bh->b_data); + mmp->mmp_time = cpu_to_le64(get_seconds()); + /* + * Start with the higher mmp_check_interval and reduce it if + * the MMP block is being updated on time. + */ -+ mmp_check_interval = max(5UL * mmp_update_interval, ++ mmp_check_interval = max(5 * mmp_update_interval, + EXT4_MMP_MIN_CHECK_INTERVAL); + mmp->mmp_check_interval = cpu_to_le16(mmp_check_interval); + bdevname(bh->b_bdev, mmp->mmp_bdevname); @@ -157,7 +161,7 @@ Index: linux-stage/fs/ext4/super.c + EXT4_FEATURE_INCOMPAT_MMP)) { + ext4_warning(sb, __func__, "kmmpd being stopped " + "since MMP feature has been disabled."); -+ EXT4_SB(sb)->s_mmp_tsk = NULL; ++ EXT4_SB(sb)->s_mmp_tsk = 0; + goto failed; + } + @@ -165,7 +169,7 @@ Index: linux-stage/fs/ext4/super.c + ext4_warning(sb, __func__, "kmmpd being stopped " + "since filesystem has been remounted as " + "readonly."); -+ EXT4_SB(sb)->s_mmp_tsk = NULL; ++ EXT4_SB(sb)->s_mmp_tsk = 0; + goto failed; + } + @@ -186,23 +190,19 @@ Index: linux-stage/fs/ext4/super.c + + retval = read_mmp_block(sb, &bh_check, mmp_block); + if (retval) { -+ ext4_error(sb, __func__, "error reading MMP" -+ "data: %d", retval); -+ EXT4_SB(sb)->s_mmp_tsk = NULL; ++ EXT4_SB(sb)->s_mmp_tsk = 0; + goto failed; + } + + mmp_check = (struct mmp_struct *)(bh_check->b_data); -+ if (mmp->mmp_seq != mmp_check->mmp_seq || ++ if (mmp->mmp_time != mmp_check->mmp_time || + memcmp(mmp->mmp_nodename, mmp_check->mmp_nodename, -+ sizeof(mmp->mmp_nodename))) { ++ sizeof(mmp->mmp_nodename))) + dump_mmp_msg(sb, mmp_check, __func__, + "Error while updating MMP info. " + "The filesystem seems to have " + "been multiply mounted."); -+ ext4_error(sb, __func__, "abort"); -+ goto failed; -+ } ++ + put_bh(bh_check); + } + @@ -210,9 +210,8 @@ Index: linux-stage/fs/ext4/super.c + * Adjust the mmp_check_interval depending on how much time + * it took for the MMP block to be written. + */ -+ mmp_check_interval = max(min(5 * diff / HZ, -+ EXT4_MMP_MAX_CHECK_INTERVAL), -+ EXT4_MMP_MIN_CHECK_INTERVAL); ++ mmp_check_interval = max(5 * diff / HZ, ++ (unsigned long) EXT4_MMP_MIN_CHECK_INTERVAL); + mmp->mmp_check_interval = cpu_to_le16(mmp_check_interval); + } + @@ -253,7 +252,6 @@ Index: linux-stage/fs/ext4/super.c + struct ext4_super_block *es = EXT4_SB(sb)->s_es; + struct buffer_head *bh = NULL; + struct mmp_struct *mmp = NULL; -+ struct mmpd_data *mmpd_data; + u32 seq; + unsigned int mmp_check_interval = le16_to_cpu(es->s_mmp_update_interval); + unsigned int wait_time = 0; @@ -345,27 +343,20 @@ Index: linux-stage/fs/ext4/super.c + goto failed; + } + -+ mmpd_data = kmalloc(sizeof(struct mmpd_data *), GFP_KERNEL); -+ if (!mmpd_data) { -+ ext4_warning(sb, KERN_ERR, "not enough memory for mmpd_data"); -+ goto failed; -+ } -+ mmpd_data->sb = sb; -+ mmpd_data->bh = bh; -+ + /* + * Start a kernel thread to update the MMP block periodically. + */ -+ EXT4_SB(sb)->s_mmp_tsk = kthread_run(kmmpd, mmpd_data, "kmmpd-%s", -+ bdevname(bh->b_bdev, -+ mmp->mmp_bdevname)); ++ EXT4_SB(sb)->s_mmp_tsk = kthread_run(kmmpd, sb, "kmmpd-%02x:%02x", ++ MAJOR(sb->s_dev), ++ MINOR(sb->s_dev)); + if (IS_ERR(EXT4_SB(sb)->s_mmp_tsk)) { -+ EXT4_SB(sb)->s_mmp_tsk = NULL; ++ EXT4_SB(sb)->s_mmp_tsk = 0; + ext4_warning(sb, __func__, "Unable to create kmmpd thread " + "for %s.", sb->s_id); + goto failed; + } + ++ brelse(bh); + return 0; + +failed: @@ -375,7 +366,7 @@ Index: linux-stage/fs/ext4/super.c static struct dentry *ext4_get_dentry(struct super_block *sb, void *vobjp) { -@@ -930,7 +1282,6 @@ static struct dentry *ext4_get_dentry(st +@@ -873,7 +1216,6 @@ static struct dentry *ext4_get_dentry(st struct inode *inode; struct dentry *result; @@ -383,7 +374,7 @@ Index: linux-stage/fs/ext4/super.c if (ino < EXT4_FIRST_INO(sb) && ino != EXT4_ROOT_INO) return ERR_PTR(-ESTALE); if (ino > le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count)) -@@ -2740,6 +3091,11 @@ static int ext4_fill_super(struct super_ +@@ -2407,6 +2749,11 @@ static int ext4_fill_super(struct super_ EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER)); @@ -395,7 +386,7 @@ Index: linux-stage/fs/ext4/super.c /* * The first inode we look at is the journal inode. Don't try * root first: it may be modified in the journal! -@@ -2978,6 +3334,8 @@ failed_mount3: +@@ -2621,6 +2968,8 @@ failed_mount3: percpu_counter_destroy(&sbi->s_freeinodes_counter); percpu_counter_destroy(&sbi->s_dirs_counter); percpu_counter_destroy(&sbi->s_dirtyblocks_counter); @@ -404,7 +395,7 @@ Index: linux-stage/fs/ext4/super.c failed_mount2: for (i = 0; i < db_count; i++) brelse(sbi->s_group_desc[i]); -@@ -3488,7 +3846,7 @@ static int ext4_remount(struct super_blo +@@ -3142,7 +3491,7 @@ static int ext4_remount(struct super_blo struct ext4_mount_options old_opts; ext4_group_t g; unsigned int journal_ioprio = DEFAULT_JOURNAL_IOPRIO; @@ -413,7 +404,7 @@ Index: linux-stage/fs/ext4/super.c #ifdef CONFIG_QUOTA int i; #endif -@@ -3607,6 +3965,13 @@ static int ext4_remount(struct super_blo +@@ -3278,6 +3627,13 @@ static int ext4_remount(struct super_blo goto restore_opts; if (!ext4_setup_super(sb, es, 0)) sb->s_flags &= ~MS_RDONLY; @@ -426,12 +417,12 @@ Index: linux-stage/fs/ext4/super.c + } } } - ext4_setup_system_zone(sb); + if (sbi->s_journal == NULL) Index: linux-stage/fs/ext4/ext4.h =================================================================== --- linux-stage.orig/fs/ext4/ext4.h +++ linux-stage/fs/ext4/ext4.h -@@ -851,7 +851,7 @@ struct ext4_super_block { +@@ -665,7 +665,7 @@ struct ext4_super_block { __le16 s_want_extra_isize; /* New inodes should reserve # bytes */ __le32 s_flags; /* Miscellaneous flags */ __le16 s_raid_stride; /* RAID stride */ @@ -440,17 +431,7 @@ Index: linux-stage/fs/ext4/ext4.h __le64 s_mmp_block; /* Block for multi-mount protection */ __le32 s_raid_stripe_width; /* blocks on all data disks (N*stride)*/ __u8 s_log_groups_per_flex; /* FLEX_BG group size */ -@@ -1005,6 +1005,9 @@ struct ext4_sb_info { - - /* workqueue for dio unwritten */ - struct workqueue_struct *dio_unwritten_wq; -+ -+ /* Kernel thread for multiple mount protection */ -+ struct task_struct *s_mmp_tsk; - }; - - static inline struct ext4_sb_info *EXT4_SB(struct super_block *sb) -@@ -1114,7 +1117,8 @@ static inline int ext4_valid_inum(struct +@@ -782,7 +782,8 @@ static inline int ext4_valid_inum(struct EXT4_FEATURE_INCOMPAT_META_BG| \ EXT4_FEATURE_INCOMPAT_EXTENTS| \ EXT4_FEATURE_INCOMPAT_64BIT| \ @@ -460,8 +441,8 @@ Index: linux-stage/fs/ext4/ext4.h #define EXT4_FEATURE_RO_COMPAT_SUPP (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER| \ EXT4_FEATURE_RO_COMPAT_LARGE_FILE| \ EXT4_FEATURE_RO_COMPAT_GDT_CSUM| \ -@@ -1296,6 +1300,50 @@ void ext4_get_group_no_and_offset(struct - extern struct proc_dir_entry *ext4_proc_root; +@@ -995,6 +996,39 @@ do { \ + #endif /* + * This structure will be used for multiple mount protection. It will be @@ -486,12 +467,6 @@ Index: linux-stage/fs/ext4/ext4.h + __le32 mmp_pad2[227]; +}; + -+/* arguments passed to the mmp thread */ -+struct mmpd_data { -+ struct buffer_head *bh; /* bh from initial read_mmp_block() */ -+ struct super_block *sb; /* super block of the fs */ -+}; -+ +/* + * Default interval in seconds to update the MMP sequence number. + */ @@ -500,14 +475,22 @@ Index: linux-stage/fs/ext4/ext4.h +/* + * Minimum interval for MMP checking in seconds. + */ -+#define EXT4_MMP_MIN_CHECK_INTERVAL 5UL -+ -+/* -+ * Maximum interval for MMP checking in seconds. -+ */ -+#define EXT4_MMP_MAX_CHECK_INTERVAL 300UL ++#define EXT4_MMP_MIN_CHECK_INTERVAL 5 + +/* * Function prototypes */ +Index: linux-stage/fs/ext4/ext4.h +=================================================================== +--- linux-stage.orig/fs/ext4/ext4.h ++++ linux-stage/fs/ext4/ext4.h +@@ -149,6 +149,8 @@ struct ext4_sb_info { + + /* workqueue for dio unwritten */ + struct workqueue_struct *dio_unwritten_wq; ++ ++ struct task_struct *s_mmp_tsk; /* Kernel thread for multiple mount protection */ + }; + + #endif /* _EXT4_SB */ diff --git a/ldiskfs/kernel_patches/patches/ext4-mmp-sles11.patch b/ldiskfs/kernel_patches/patches/ext4-mmp-sles11.patch index 0857e0f..3d6313c 100644 --- a/ldiskfs/kernel_patches/patches/ext4-mmp-sles11.patch +++ b/ldiskfs/kernel_patches/patches/ext4-mmp-sles11.patch @@ -2,25 +2,25 @@ Index: linux-stage/fs/ext4/super.c =================================================================== --- linux-stage.orig/fs/ext4/super.c +++ linux-stage/fs/ext4/super.c -@@ -41,6 +41,8 @@ +@@ -39,6 +39,8 @@ + #include #include - #include #include +#include +#include #include "ext4.h" #include "ext4_jbd2.h" -@@ -666,6 +668,8 @@ static void ext4_put_super(struct super_ +@@ -600,6 +602,8 @@ static void ext4_put_super(struct super_ invalidate_bdev(sbi->journal_bdev); ext4_blkdev_remove(sbi); } + if (sbi->s_mmp_tsk) + kthread_stop(sbi->s_mmp_tsk); sb->s_fs_info = NULL; - /* - * Now that we are completely done shutting down the -@@ -886,7 +890,6 @@ static int ext4_show_options(struct seq_ + kfree(sbi); + return; +@@ -808,7 +812,6 @@ static int ext4_show_options(struct seq_ if (!test_opt(sb, DELALLOC)) seq_puts(seq, ",nodelalloc"); @@ -28,10 +28,10 @@ Index: linux-stage/fs/ext4/super.c if (sbi->s_stripe) seq_printf(seq, ",stripe=%lu", sbi->s_stripe); /* -@@ -921,6 +924,350 @@ static int ext4_show_options(struct seq_ - return 0; +@@ -831,6 +834,340 @@ static int ext4_show_options(struct seq_ } + + +/* + * Write the MMP block using WRITE_SYNC to try to get the block on-disk @@ -110,9 +110,9 @@ Index: linux-stage/fs/ext4/super.c + */ +static int kmmpd(void *data) +{ -+ struct super_block *sb = ((struct mmpd_data *) data)->sb; -+ struct buffer_head *bh = ((struct mmpd_data *) data)->bh; ++ struct super_block *sb = (struct super_block *) data; + struct ext4_super_block *es = EXT4_SB(sb)->s_es; ++ struct buffer_head *bh = NULL; + struct mmp_struct *mmp; + unsigned long mmp_block; + u32 seq = 0; @@ -124,13 +124,17 @@ Index: linux-stage/fs/ext4/super.c + int retval; + + mmp_block = le64_to_cpu(es->s_mmp_block); ++ retval = read_mmp_block(sb, &bh, mmp_block); ++ if (retval) ++ goto failed; ++ + mmp = (struct mmp_struct *)(bh->b_data); + mmp->mmp_time = cpu_to_le64(get_seconds()); + /* + * Start with the higher mmp_check_interval and reduce it if + * the MMP block is being updated on time. + */ -+ mmp_check_interval = max(5UL * mmp_update_interval, ++ mmp_check_interval = max(5 * mmp_update_interval, + EXT4_MMP_MIN_CHECK_INTERVAL); + mmp->mmp_check_interval = cpu_to_le16(mmp_check_interval); + bdevname(bh->b_bdev, mmp->mmp_bdevname); @@ -161,7 +165,7 @@ Index: linux-stage/fs/ext4/super.c + EXT4_FEATURE_INCOMPAT_MMP)) { + ext4_warning(sb, __func__, "kmmpd being stopped " + "since MMP feature has been disabled."); -+ EXT4_SB(sb)->s_mmp_tsk = NULL; ++ EXT4_SB(sb)->s_mmp_tsk = 0; + goto failed; + } + @@ -169,7 +173,7 @@ Index: linux-stage/fs/ext4/super.c + ext4_warning(sb, __func__, "kmmpd being stopped " + "since filesystem has been remounted as " + "readonly."); -+ EXT4_SB(sb)->s_mmp_tsk = NULL; ++ EXT4_SB(sb)->s_mmp_tsk = 0; + goto failed; + } + @@ -190,24 +194,19 @@ Index: linux-stage/fs/ext4/super.c + + retval = read_mmp_block(sb, &bh_check, mmp_block); + if (retval) { -+ ext4_error(sb, __func__, "error reading MMP" -+ "data: %d", retval); -+ -+ EXT4_SB(sb)->s_mmp_tsk = NULL; ++ EXT4_SB(sb)->s_mmp_tsk = 0; + goto failed; + } + + mmp_check = (struct mmp_struct *)(bh_check->b_data); -+ if (mmp->mmp_seq != mmp_check->mmp_seq || ++ if (mmp->mmp_time != mmp_check->mmp_time || + memcmp(mmp->mmp_nodename, mmp_check->mmp_nodename, -+ sizeof(mmp->mmp_nodename))) { ++ sizeof(mmp->mmp_nodename))) + dump_mmp_msg(sb, mmp_check, __func__, + "Error while updating MMP info. " + "The filesystem seems to have " + "been multiply mounted."); -+ ext4_error(sb, __func__, "abort"); -+ goto failed; -+ } ++ + put_bh(bh_check); + } + @@ -215,9 +214,8 @@ Index: linux-stage/fs/ext4/super.c + * Adjust the mmp_check_interval depending on how much time + * it took for the MMP block to be written. + */ -+ mmp_check_interval = max(min(5 * diff / HZ, -+ EXT4_MMP_MAX_CHECK_INTERVAL), -+ EXT4_MMP_MIN_CHECK_INTERVAL); ++ mmp_check_interval = max(5 * diff / HZ, ++ (unsigned long) EXT4_MMP_MIN_CHECK_INTERVAL); + mmp->mmp_check_interval = cpu_to_le16(mmp_check_interval); + } + @@ -258,7 +256,6 @@ Index: linux-stage/fs/ext4/super.c + struct ext4_super_block *es = EXT4_SB(sb)->s_es; + struct buffer_head *bh = NULL; + struct mmp_struct *mmp = NULL; -+ struct mmpd_data *mmpd_data; + u32 seq; + unsigned int mmp_check_interval = le16_to_cpu(es->s_mmp_update_interval); + unsigned int wait_time = 0; @@ -348,27 +345,20 @@ Index: linux-stage/fs/ext4/super.c + goto failed; + } + -+ mmpd_data = kmalloc(sizeof(struct mmpd_data *), GFP_KERNEL); -+ if (!mmpd_data) { -+ ext4_warning(sb, KERN_ERR, "not enough memory for mmpd_data"); -+ goto failed; -+ } -+ mmpd_data->sb = sb; -+ mmpd_data->bh = bh; -+ + /* + * Start a kernel thread to update the MMP block periodically. + */ -+ EXT4_SB(sb)->s_mmp_tsk = kthread_run(kmmpd, mmpd_data, "kmmpd-%s", -+ bdevname(bh->b_bdev, -+ mmp->mmp_bdevname)); ++ EXT4_SB(sb)->s_mmp_tsk = kthread_run(kmmpd, sb, "kmmpd-%02x:%02x", ++ MAJOR(sb->s_dev), ++ MINOR(sb->s_dev)); + if (IS_ERR(EXT4_SB(sb)->s_mmp_tsk)) { -+ EXT4_SB(sb)->s_mmp_tsk = NULL; ++ EXT4_SB(sb)->s_mmp_tsk = 0; + ext4_warning(sb, __func__, "Unable to create kmmpd thread " + "for %s.", sb->s_id); + goto failed; + } + ++ brelse(bh); + return 0; + +failed: @@ -377,9 +367,9 @@ Index: linux-stage/fs/ext4/super.c +} + static struct inode *ext4_nfs_get_inode(struct super_block *sb, - u64 ino, u32 generation) + u64 ino, u32 generation) { -@@ -2767,6 +3114,11 @@ static int ext4_fill_super(struct super_ +@@ -2371,6 +2708,11 @@ static int ext4_fill_super(struct super_ EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER)); @@ -391,7 +381,7 @@ Index: linux-stage/fs/ext4/super.c /* * The first inode we look at is the journal inode. Don't try * root first: it may be modified in the journal! -@@ -3003,6 +3355,8 @@ failed_mount3: +@@ -2571,6 +2913,8 @@ failed_mount3: percpu_counter_destroy(&sbi->s_freeinodes_counter); percpu_counter_destroy(&sbi->s_dirs_counter); percpu_counter_destroy(&sbi->s_dirtyblocks_counter); @@ -400,16 +390,16 @@ Index: linux-stage/fs/ext4/super.c failed_mount2: for (i = 0; i < db_count; i++) brelse(sbi->s_group_desc[i]); -@@ -3512,7 +3866,7 @@ static int ext4_remount(struct super_blo +@@ -3086,7 +3430,7 @@ static int ext4_remount(struct super_blo struct ext4_mount_options old_opts; ext4_group_t g; - unsigned int journal_ioprio = DEFAULT_JOURNAL_IOPRIO; + unsigned int journal_ioprio = DEFAULT_JOURNAL_IOPRIO; - int err; + int err = 0; #ifdef CONFIG_QUOTA int i; #endif -@@ -3634,6 +3988,13 @@ static int ext4_remount(struct super_blo +@@ -3211,6 +3555,13 @@ static int ext4_remount(struct super_blo goto restore_opts; if (!ext4_setup_super(sb, es, 0)) sb->s_flags &= ~MS_RDONLY; @@ -422,12 +412,12 @@ Index: linux-stage/fs/ext4/super.c + } } } - ext4_setup_system_zone(sb); + #ifdef CONFIG_QUOTA Index: linux-stage/fs/ext4/ext4.h =================================================================== --- linux-stage.orig/fs/ext4/ext4.h +++ linux-stage/fs/ext4/ext4.h -@@ -875,7 +875,7 @@ struct ext4_super_block { +@@ -660,7 +660,7 @@ struct ext4_super_block { __le16 s_want_extra_isize; /* New inodes should reserve # bytes */ __le32 s_flags; /* Miscellaneous flags */ __le16 s_raid_stride; /* RAID stride */ @@ -436,17 +426,7 @@ Index: linux-stage/fs/ext4/ext4.h __le64 s_mmp_block; /* Block for multi-mount protection */ __le32 s_raid_stripe_width; /* blocks on all data disks (N*stride)*/ __u8 s_log_groups_per_flex; /* FLEX_BG group size */ -@@ -1022,6 +1022,9 @@ struct ext4_sb_info { - - /* workqueue for dio unwritten */ - struct workqueue_struct *dio_unwritten_wq; -+ -+ /* Kernel thread for multiple mount protection */ -+ struct task_struct *s_mmp_tsk; - }; - - static inline struct ext4_sb_info *EXT4_SB(struct super_block *sb) -@@ -1130,7 +1133,8 @@ static inline int ext4_valid_inum(struct +@@ -777,7 +777,8 @@ static inline int ext4_valid_inum(struct EXT4_FEATURE_INCOMPAT_META_BG| \ EXT4_FEATURE_INCOMPAT_EXTENTS| \ EXT4_FEATURE_INCOMPAT_64BIT| \ @@ -456,8 +436,8 @@ Index: linux-stage/fs/ext4/ext4.h #define EXT4_FEATURE_RO_COMPAT_SUPP (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER| \ EXT4_FEATURE_RO_COMPAT_LARGE_FILE| \ EXT4_FEATURE_RO_COMPAT_GDT_CSUM| \ -@@ -1312,6 +1316,50 @@ void ext4_get_group_no_and_offset(struct - extern struct proc_dir_entry *ext4_proc_root; +@@ -981,6 +982,39 @@ do { \ + #endif /* + * This structure will be used for multiple mount protection. It will be @@ -482,12 +462,6 @@ Index: linux-stage/fs/ext4/ext4.h + __le32 mmp_pad2[227]; +}; + -+/* arguments passed to the mmp thread */ -+struct mmpd_data { -+ struct buffer_head *bh; /* bh from initial read_mmp_block() */ -+ struct super_block *sb; /* super block of the fs */ -+}; -+ +/* + * Default interval in seconds to update the MMP sequence number. + */ @@ -496,14 +470,22 @@ Index: linux-stage/fs/ext4/ext4.h +/* + * Minimum interval for MMP checking in seconds. + */ -+#define EXT4_MMP_MIN_CHECK_INTERVAL 5UL -+ -+/* -+ * Maximum interval for MMP checking in seconds. -+ */ -+#define EXT4_MMP_MAX_CHECK_INTERVAL 300UL ++#define EXT4_MMP_MIN_CHECK_INTERVAL 5 + +/* * Function prototypes */ +Index: linux-stage/fs/ext4/ext4_sb.h +=================================================================== +--- linux-stage.orig/fs/ext4/ext4.h ++++ linux-stage/fs/ext4/ext4.h +@@ -149,6 +149,8 @@ struct ext4_sb_info { + + /* workqueue for dio unwritten */ + struct workqueue_struct *dio_unwritten_wq; ++ ++ struct task_struct *s_mmp_tsk; /* Kernel thread for multiple mount protection */ + }; + + static inline struct ext4_sb_info *EXT4_SB(struct super_block *sb) -- 1.8.3.1