From 8a586da755168a02f9cd56bfae7ee9e030556055 Mon Sep 17 00:00:00 2001 From: adilger Date: Wed, 29 Jan 2003 01:09:34 +0000 Subject: [PATCH] Merge extN patch fixes from b_intent to b_md. --- lustre/extN/ext3-unmount_sync.diff | 59 ++++++++++++++++++++++++++++++++ lustre/extN/ext3-use-after-free.diff | 65 ++++++++++++++++++++++++++++++++++++ 2 files changed, 124 insertions(+) create mode 100644 lustre/extN/ext3-unmount_sync.diff create mode 100644 lustre/extN/ext3-use-after-free.diff diff --git a/lustre/extN/ext3-unmount_sync.diff b/lustre/extN/ext3-unmount_sync.diff new file mode 100644 index 0000000..1f9b796 --- /dev/null +++ b/lustre/extN/ext3-unmount_sync.diff @@ -0,0 +1,59 @@ +From adilger@clusterfs.com Mon Dec 2 10:26:44 2002 +Date: Mon, 2 Dec 2002 10:26:44 -0700 +From: Andreas Dilger +To: Lustre LLNL Mailing list , + Lustre Development Mailing List +Subject: Re: data corrupting bug in 2.4.20 ext3, data=journal +Message-ID: <20021202102644.H1422@schatzie.adilger.int> +Mail-Followup-To: Lustre LLNL Mailing list , + Lustre Development Mailing List +Mime-Version: 1.0 +Content-Type: text/plain; charset=us-ascii +Content-Disposition: inline +User-Agent: Mutt/1.2.5.1i +X-GPG-Key: 1024D/0D35BED6 +X-GPG-Fingerprint: 7A37 5D79 BF1B CECA D44F 8A29 A488 39F5 0D35 BED6 +Status: RO +Content-Length: 1160 +Lines: 39 + +Here is the new-improved fix for the ext3 discarding data at umount bug +discovered late last week. To be used instead of the previous ext3 fix. + +Sadly, this is completely unrelated to the problems Mike is having with +ext3 under UML, since it is an unmount-time problem. + +----- Forwarded message from "Stephen C. Tweedie" ----- +The attached patch seems to fix things for me. + +Cheers, + Stephen + + +--- linux-2.4-ext3merge/fs/ext3/super.c.=K0027=.orig 2002-12-02 15:35:13.000000000 +0000 ++++ linux-2.4-ext3merge/fs/ext3/super.c 2002-12-02 15:35:14.000000000 +0000 +@@ -1640,7 +1640,12 @@ + sb->s_dirt = 0; + target = log_start_commit(EXT3_SB(sb)->s_journal, NULL); + +- if (do_sync_supers) { ++ /* ++ * Tricky --- if we are unmounting, the write really does need ++ * to be synchronous. We can detect that by looking for NULL in ++ * sb->s_root. ++ */ ++ if (do_sync_supers || !sb->s_root) { + unlock_super(sb); + log_wait_commit(EXT3_SB(sb)->s_journal, target); + lock_super(sb); + + +----- End forwarded message ----- + +Cheers, Andreas +-- +Andreas Dilger +http://sourceforge.net/projects/ext2resize/ +http://www-mddsp.enel.ucalgary.ca/People/adilger/ + + diff --git a/lustre/extN/ext3-use-after-free.diff b/lustre/extN/ext3-use-after-free.diff new file mode 100644 index 0000000..8cd673f --- /dev/null +++ b/lustre/extN/ext3-use-after-free.diff @@ -0,0 +1,65 @@ + + +If ext3_add_nondir() fails it will do an iput() of the inode. But we +continue to run ext3_mark_inode_dirty() against the potentially-freed +inode. This oopses when slab poisoning is enabled. + +Fix it so that we only run ext3_mark_inode_dirty() if the inode was +successfully instantiated. + +This bug was added in 2.4.20-pre9. + + + fs/ext3/namei.c | 11 +++++------ + 1 files changed, 5 insertions(+), 6 deletions(-) + +--- 24/fs/ext3/namei.c~ext3-use-after-free Sun Dec 15 11:27:50 2002 ++++ 24-akpm/fs/ext3/namei.c Sun Dec 15 11:27:50 2002 +@@ -429,8 +429,11 @@ static int ext3_add_nondir(handle_t *han + { + int err = ext3_add_entry(handle, dentry, inode); + if (!err) { +- d_instantiate(dentry, inode); +- return 0; ++ err = ext3_mark_inode_dirty(handle, inode); ++ if (err == 0) { ++ d_instantiate(dentry, inode); ++ return 0; ++ } + } + ext3_dec_count(handle, inode); + iput(inode); +@@ -465,7 +468,6 @@ static int ext3_create (struct inode * d + inode->i_fop = &ext3_file_operations; + inode->i_mapping->a_ops = &ext3_aops; + err = ext3_add_nondir(handle, dentry, inode); +- ext3_mark_inode_dirty(handle, inode); + } + ext3_journal_stop(handle, dir); + return err; +@@ -490,7 +492,6 @@ static int ext3_mknod (struct inode * di + if (!IS_ERR(inode)) { + init_special_inode(inode, mode, rdev); + err = ext3_add_nondir(handle, dentry, inode); +- ext3_mark_inode_dirty(handle, inode); + } + ext3_journal_stop(handle, dir); + return err; +@@ -934,7 +935,6 @@ static int ext3_symlink (struct inode * + } + inode->u.ext3_i.i_disksize = inode->i_size; + err = ext3_add_nondir(handle, dentry, inode); +- ext3_mark_inode_dirty(handle, inode); + out_stop: + ext3_journal_stop(handle, dir); + return err; +@@ -971,7 +971,6 @@ static int ext3_link (struct dentry * ol + atomic_inc(&inode->i_count); + + err = ext3_add_nondir(handle, dentry, inode); +- ext3_mark_inode_dirty(handle, inode); + ext3_journal_stop(handle, dir); + return err; + } + +_ -- 1.8.3.1