Hi, On Thu, 2003-06-12 at 22:04, Linux Tard wrote: > I've tried to find my answer to this question but I > have not (yet). Any assistance or expert knowledge is > greatly appreciated! > > PROBLEM: mounting an ext3 volume 'read only' results > in a different md5sum hash value for the volume than > when the same volume is *not* mounted The patch below seems to fix this for me. It simply skips journal superblock updates when the superblock is already marked fully-recovered and nothing more has been written to the journal since then. That allows jbd to keep updating its internal transaction sequence state to maintain monotonically increasing transaction numbers on disk, without those updates leaking to disk on a readonly volume. I've been testing this lightly with LVM snapshots (which warn you if you try to write to the snapshot), and the patch does cure stray unexpected writes on readonly mounts there. Cheers, Stephen
--- linux-2.4.20/fs/jbd/journal.c.=K0004=.orig +++ linux-2.4.20/fs/jbd/journal.c @@ -947,6 +947,22 @@ void journal_update_superblock(journal_t journal_superblock_t *sb = journal->j_superblock; struct buffer_head *bh = journal->j_sb_buffer; + /* As a special case, if the on-disk copy is already marked as + * needing no recovery (s_start == 0) and there are no + * outstanding transactions in the filesystem, 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 (sb->s_start == 0 && + journal->j_tail_sequence == journal->j_transaction_sequence) { + jbd_debug(1,"JBD: Skipping superblock update on recovered sb " + "(start %ld, seq %d, errno %d)\n", + journal->j_tail, journal->j_tail_sequence, + journal->j_errno); + goto out; + } + jbd_debug(1,"JBD: updating superblock (start %ld, seq %d, errno %d)\n", journal->j_tail, journal->j_tail_sequence, journal->j_errno); @@ -960,6 +976,7 @@ void journal_update_superblock(journal_t if (wait) wait_on_buffer(bh); +out: /* If we have just flushed the log (by marking s_start==0), then * any future commit will have to be careful to update the * superblock again to re-record the true start of the log. */