If an attempt to perform a barrier-based write fails because the disk doesn't
support barriers, drop a message and disable barriers.


---

 25-akpm/fs/jbd/commit.c |   21 +++++++++++++++++++--
 1 files changed, 19 insertions(+), 2 deletions(-)

diff -puN fs/jbd/commit.c~jbd-barrier-fallback-on-failure fs/jbd/commit.c
--- 25/fs/jbd/commit.c~jbd-barrier-fallback-on-failure	2004-05-21 23:48:44.469550024 -0700
+++ 25-akpm/fs/jbd/commit.c	2004-05-21 23:50:58.396190080 -0700
@@ -638,11 +638,28 @@ wait_for_iobuf:
 	JBUFFER_TRACE(descriptor, "write commit block");
 	{
 		struct buffer_head *bh = jh2bh(descriptor);
+		int ret;
+
 		set_buffer_uptodate(bh);
 		if (journal->j_flags & JFS_BARRIER)
 			set_buffer_ordered(bh);
-		sync_dirty_buffer(bh);
-		if (unlikely(!buffer_uptodate(bh)))
+		ret = sync_dirty_buffer(bh);
+		if (ret == -EOPNOTSUPP && (journal->j_flags & JFS_BARRIER)) {
+			char b[BDEVNAME_SIZE];
+
+			printk(KERN_WARNING
+				"JBD: barrier-based sync failed on %s - "
+				"bisabling barriers\n",
+				bdevname(journal->j_dev, b));
+			spin_lock(&journal->j_state_lock);
+			journal->j_flags &= ~JFS_BARRIER;
+			spin_lock(&journal->j_state_lock);
+
+			/* And try again, without the barrier */
+			clear_buffer_ordered(bh);
+			ret = sync_dirty_buffer(bh);
+		}
+		if (unlikely(ret == -EIO))
 			err = -EIO;
 		put_bh(bh);		/* One for getblk() */
 		journal_put_journal_head(descriptor);

_