]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] JBD: honour read-only mounts more carefully
authorAndrew Morton <akpm@digeo.com>
Fri, 20 Jun 2003 15:16:03 +0000 (08:16 -0700)
committerLinus Torvalds <torvalds@home.transmeta.com>
Fri, 20 Jun 2003 15:16:03 +0000 (08:16 -0700)
From: "Stephen C. Tweedie" <sct@redhat.com>

ext3 has long had a problem wherein it will unnecessarily write to a
read-only filesystem during the mount process.  It does this in preparing the
journal superblock's sequence numbers.

But if the filesystem was shut down cleanly we do not need to do this.
Detect the situation and avoid modifying and writing out the journal
superblock.

fs/jbd/journal.c

index e734d3d3df5ee16762b4272c2d8604ba8c2efb26..d7ab5776d75bf376bf847b9ddc26b6ae666ea98a 100644 (file)
@@ -872,6 +872,22 @@ void journal_update_superblock(journal_t *journal, int wait)
        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;
+       }
+
        spin_lock(&journal->j_state_lock);
        jbd_debug(1,"JBD: updating superblock (start %ld, seq %d, errno %d)\n",
                  journal->j_tail, journal->j_tail_sequence, journal->j_errno);
@@ -888,6 +904,7 @@ void journal_update_superblock(journal_t *journal, int wait)
        else
                ll_rw_block(WRITE, 1, &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. */