fs/ext3/super.c         |   31 ++++++++++++++++++++++++-------
 fs/jbd/commit.c         |    3 ++-
 include/linux/ext3_fs.h |    1 +
 include/linux/jbd.h     |    1 +
 4 files changed, 28 insertions(+), 8 deletions(-)

diff -puN fs/ext3/super.c~jbd-barrier-selection fs/ext3/super.c
--- 25/fs/ext3/super.c~jbd-barrier-selection	2003-10-14 18:24:40.000000000 -0700
+++ 25-akpm/fs/ext3/super.c	2003-10-14 22:13:44.000000000 -0700
@@ -534,7 +534,8 @@ enum {
 	Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl, Opt_noload,
 	Opt_commit, Opt_journal_update, Opt_journal_inum,
 	Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback,
-	Opt_ignore, Opt_err,
+	Opt_ignore, Opt_barrier,
+	Opt_err,
 };
 
 static match_table_t tokens = {
@@ -573,6 +574,7 @@ static match_table_t tokens = {
 	{Opt_ignore, "noquota"},
 	{Opt_ignore, "quota"},
 	{Opt_ignore, "usrquota"},
+	{Opt_barrier, "barrier=%u"},
 	{Opt_err, NULL}
 };
 
@@ -760,6 +762,14 @@ static int parse_options (char * options
 		case Opt_abort:
 			set_opt(sbi->s_mount_opt, ABORT);
 			break;
+		case Opt_barrier:
+			if (match_int(&args[0], &option))
+				return 0;
+			if (option)
+				set_opt(sbi->s_mount_opt, BARRIER);
+			else
+				clear_opt(sbi->s_mount_opt, BARRIER);
+			break;
 		case Opt_ignore:
 			break;
 		default:
@@ -1413,16 +1423,23 @@ out_fail:
  * initial mount, once the journal has been initialised but before we've
  * done any recovery; and again on any subsequent remount. 
  */
-static void ext3_init_journal_params(struct ext3_sb_info *sbi, 
-				     journal_t *journal)
+static void ext3_init_journal_params(struct super_block *sb, journal_t *journal)
 {
+	struct ext3_sb_info *sbi = EXT3_SB(sb);
+
 	if (sbi->s_commit_interval)
 		journal->j_commit_interval = sbi->s_commit_interval;
 	/* We could also set up an ext3-specific default for the commit
 	 * interval here, but for now we'll just fall back to the jbd
 	 * default. */
-}
 
+	spin_lock(&journal->j_state_lock);
+	if (test_opt(sb, BARRIER))
+		journal->j_flags |= JFS_BARRIER;
+	else
+		journal->j_flags &= ~JFS_BARRIER;
+	spin_unlock(&journal->j_state_lock);
+}
 
 static journal_t *ext3_get_journal(struct super_block *sb, int journal_inum)
 {
@@ -1459,7 +1476,7 @@ static journal_t *ext3_get_journal(struc
 		iput(journal_inode);
 	}
 	journal->j_private = sb;
-	ext3_init_journal_params(EXT3_SB(sb), journal);
+	ext3_init_journal_params(sb, journal);
 	return journal;
 }
 
@@ -1537,7 +1554,7 @@ static journal_t *ext3_get_dev_journal(s
 		goto out_journal;
 	}
 	EXT3_SB(sb)->journal_bdev = bdev;
-	ext3_init_journal_params(EXT3_SB(sb), journal);
+	ext3_init_journal_params(sb, journal);
 	return journal;
 out_journal:
 	journal_destroy(journal);
@@ -1830,7 +1847,7 @@ int ext3_remount (struct super_block * s
 
 	es = sbi->s_es;
 
-	ext3_init_journal_params(sbi, sbi->s_journal);
+	ext3_init_journal_params(sb, sbi->s_journal);
 
 	if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY)) {
 		if (sbi->s_mount_opt & EXT3_MOUNT_ABORT)
diff -puN include/linux/ext3_fs.h~jbd-barrier-selection include/linux/ext3_fs.h
--- 25/include/linux/ext3_fs.h~jbd-barrier-selection	2003-10-14 18:24:40.000000000 -0700
+++ 25-akpm/include/linux/ext3_fs.h	2003-10-14 18:24:40.000000000 -0700
@@ -324,6 +324,7 @@ struct ext3_inode {
 #define EXT3_MOUNT_NO_UID32		0x2000  /* Disable 32-bit UIDs */
 #define EXT3_MOUNT_XATTR_USER		0x4000	/* Extended user attributes */
 #define EXT3_MOUNT_POSIX_ACL		0x8000	/* POSIX Access Control Lists */
+#define EXT3_MOUNT_BARRIER		0x10000 /* Use block barriers */
 
 /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */
 #ifndef _LINUX_EXT2_FS_H
diff -puN include/linux/jbd.h~jbd-barrier-selection include/linux/jbd.h
--- 25/include/linux/jbd.h~jbd-barrier-selection	2003-10-14 18:24:40.000000000 -0700
+++ 25-akpm/include/linux/jbd.h	2003-10-14 18:24:40.000000000 -0700
@@ -825,6 +825,7 @@ struct journal_s
 #define JFS_ACK_ERR	0x004	/* The errno in the sb has been acked */
 #define JFS_FLUSHED	0x008	/* The journal superblock has been flushed */
 #define JFS_LOADED	0x010	/* The journal superblock has been loaded */
+#define JFS_BARRIER	0x020	/* Use IDE barriers */
 
 /* 
  * Function declarations for the journaling transaction and buffer
diff -puN fs/jbd/commit.c~jbd-barrier-selection fs/jbd/commit.c
--- 25/fs/jbd/commit.c~jbd-barrier-selection	2003-10-14 18:24:40.000000000 -0700
+++ 25-akpm/fs/jbd/commit.c	2003-10-14 22:23:23.000000000 -0700
@@ -613,7 +613,8 @@ wait_for_iobuf:
 	{
 		struct buffer_head *bh = jh2bh(descriptor);
 		set_buffer_uptodate(bh);
-		set_buffer_ordered(bh);
+		if (journal->j_flags & JFS_BARRIER)
+			set_buffer_ordered(bh);
 		sync_dirty_buffer(bh);
 		clear_buffer_ordered(bh);
 		if (unlikely(!buffer_uptodate(bh)))

_