From 262b0560ab38f26f555c0b590b79deed1b960e86 Mon Sep 17 00:00:00 2001 From: adilger Date: Wed, 29 Jan 2003 01:08:24 +0000 Subject: [PATCH] Add the sync-on-unmount fix, and another fix which avoids accessing freed inodes upon ENOSPC or other errors (from AKPM). The Makefile should be smart enough to detect if they need to be applied. --- 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