Re: Regarding hashing, ext3, and kjournald

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

 



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. */

[Index of Archives]         [Linux RAID]     [Kernel Development]     [Red Hat Install]     [Video 4 Linux]     [Postgresql]     [Fedora]     [Gimp]     [Yosemite News]

  Powered by Linux