summaryrefslogtreecommitdiffstats
path: root/fs/ext4/ext4_jbd2.h
diff options
context:
space:
mode:
authorCurt Wohlgemuth <curtw@google.com>2011-08-13 17:25:18 +0200
committerTheodore Ts'o <tytso@mit.edu>2011-08-13 17:25:18 +0200
commit441c850857148935babe000fc2ba1455fe54a6a9 (patch)
treeaa0ef8ca32a49b2daf072f851938af3f2db35a90 /fs/ext4/ext4_jbd2.h
parentLinux 3.1-rc1 (diff)
downloadlinux-441c850857148935babe000fc2ba1455fe54a6a9.tar.xz
linux-441c850857148935babe000fc2ba1455fe54a6a9.zip
ext4: Fix ext4_should_writeback_data() for no-journal mode
ext4_should_writeback_data() had an incorrect sequence of tests to determine if it should return 0 or 1: in particular, even in no-journal mode, 0 was being returned for a non-regular-file inode. This meant that, in non-journal mode, we would use ext4_journalled_aops for directories, symlinks, and other non-regular files. However, calling journalled aop callbacks when there is no valid handle, can cause problems. This would cause a kernel crash with Jan Kara's commit 2d859db3e4 ("ext4: fix data corruption in inodes with journalled data"), because we now dereference 'handle' in ext4_journalled_write_end(). I also added BUG_ONs to check for a valid handle in the obviously journal-only aops callbacks. I tested this running xfstests with a scratch device in these modes: - no-journal - data=ordered - data=writeback - data=journal All work fine; the data=journal run has many failures and a crash in xfstests 074, but this is no different from a vanilla kernel. Signed-off-by: Curt Wohlgemuth <curtw@google.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> Cc: stable@kernel.org
Diffstat (limited to 'fs/ext4/ext4_jbd2.h')
-rw-r--r--fs/ext4/ext4_jbd2.h4
1 files changed, 2 insertions, 2 deletions
diff --git a/fs/ext4/ext4_jbd2.h b/fs/ext4/ext4_jbd2.h
index bb85757689b6..5802fa1dab18 100644
--- a/fs/ext4/ext4_jbd2.h
+++ b/fs/ext4/ext4_jbd2.h
@@ -289,10 +289,10 @@ static inline int ext4_should_order_data(struct inode *inode)
static inline int ext4_should_writeback_data(struct inode *inode)
{
- if (!S_ISREG(inode->i_mode))
- return 0;
if (EXT4_JOURNAL(inode) == NULL)
return 1;
+ if (!S_ISREG(inode->i_mode))
+ return 0;
if (ext4_test_inode_flag(inode, EXT4_INODE_JOURNAL_DATA))
return 0;
if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA)