[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: jbd count incremented *even* if volume is mounted RO?



Hi,

On Fri, 2003-06-13 at 09:42, Andrew Morton wrote:

> JBD bogusly increments the transaction sequence in the journal superblock
> by one on each mount/unmount.  

A lot of ext3 internals absolutely rely on making sure that those
sequence numbers never get reused.  It's a major opportunity for
recovery failures if that goes wrong.

Fortunately the snapshotting support code already has a "JFS_FLUSHED"
flag which tells the commit code that the journal on disk is marked as
needing no recovery (s_start == 0), and that the jbd sb needs to be
updated on disk before a commit can start.  We can reuse that in this
case to defer the initial update of the superblock sequence information
in the case where we've got no recovery required.

That should allow us to maintain the new transaction sequence in memory,
but avoid writing it to disk in the case where we're readonly and fully
recovered already.

The patch chunk below fixes the initial flush of the jbd sb to disk for
me, but I'm still seeing stray writes elsewhere during mount and unmount
on a completely readonly device --- more when I've fixed this
completely.

Cheers,
 Stephen

--- linux-2.4.20/fs/jbd/journal.c.=K0004=.orig
+++ linux-2.4.20/fs/jbd/journal.c
@@ -855,8 +855,16 @@ static int journal_reset (journal_t *jou
 
 	journal->j_max_transaction_buffers = journal->j_maxlen / 4;
 
-	/* Add the dynamic fields and write it to disk. */
-	journal_update_superblock(journal, 1);
+	/* Add the dynamic fields and write it to disk.  As a special
+	 * case, if the on-disk copy is already marked as needing no
+	 * recovery (s_start == 0), then we can safely defer the
+	 * superblock update until the next commit by setting
+	 * JFS_FLUSHED.  This avoids attempting a write to a
+	 * potential-readonly device. */
+	if (ntohl(sb->s_start))
+		journal_update_superblock(journal, 1);
+	else
+		journal->j_flags |= JFS_FLUSHED;
 
 	lock_journal(journal);
 	journal_start_thread(journal);

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]