linux-ext4.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/3] ext4: Simplify ext4_commit_super()'s function signature
@ 2009-05-01  4:37 Theodore Ts'o
  2009-05-01  4:37 ` [PATCH 2/3] ext4: Fix and simplify s_dirt handling Theodore Ts'o
  0 siblings, 1 reply; 12+ messages in thread
From: Theodore Ts'o @ 2009-05-01  4:37 UTC (permalink / raw)
  To: Ext4 Developers List; +Cc: Theodore Ts'o

The ext4_commit_super() function took both a struct super_block * and
a struct ext4_super_block *, but the struct ext4_super_block can be
derived from the struct super_block.

Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
---
 fs/ext4/super.c |   33 ++++++++++++++++-----------------
 1 files changed, 16 insertions(+), 17 deletions(-)

diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 3e509bc..ad4c9be 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -54,8 +54,7 @@ static struct kset *ext4_kset;
 
 static int ext4_load_journal(struct super_block *, struct ext4_super_block *,
 			     unsigned long journal_devnum);
-static int ext4_commit_super(struct super_block *sb,
-			      struct ext4_super_block *es, int sync);
+static int ext4_commit_super(struct super_block *sb, int sync);
 static void ext4_mark_recovery_complete(struct super_block *sb,
 					struct ext4_super_block *es);
 static void ext4_clear_journal_err(struct super_block *sb,
@@ -306,7 +305,7 @@ static void ext4_handle_error(struct super_block *sb)
 		printk(KERN_CRIT "Remounting filesystem read-only\n");
 		sb->s_flags |= MS_RDONLY;
 	}
-	ext4_commit_super(sb, es, 1);
+	ext4_commit_super(sb, 1);
 	if (test_opt(sb, ERRORS_PANIC))
 		panic("EXT4-fs (device %s): panic forced after error\n",
 			sb->s_id);
@@ -448,7 +447,7 @@ __acquires(bitlock)
 	if (test_opt(sb, ERRORS_CONT)) {
 		EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS;
 		es->s_state |= cpu_to_le16(EXT4_ERROR_FS);
-		ext4_commit_super(sb, es, 0);
+		ext4_commit_super(sb, 0);
 		return;
 	}
 	ext4_unlock_group(sb, grp);
@@ -577,7 +576,7 @@ static void ext4_put_super(struct super_block *sb)
 	if (!(sb->s_flags & MS_RDONLY)) {
 		EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
 		es->s_state = cpu_to_le16(sbi->s_mount_state);
-		ext4_commit_super(sb, es, 1);
+		ext4_commit_super(sb, 1);
 	}
 	if (sbi->s_proc) {
 		remove_proc_entry(sb->s_id, ext4_proc_root);
@@ -1596,7 +1595,7 @@ static int ext4_setup_super(struct super_block *sb, struct ext4_super_block *es,
 	if (sbi->s_journal)
 		EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
 
-	ext4_commit_super(sb, es, 1);
+	ext4_commit_super(sb, 1);
 	if (test_opt(sb, DEBUG))
 		printk(KERN_INFO "[EXT4 FS bs=%lu, gc=%u, "
 				"bpg=%lu, ipg=%lu, mo=%04lx]\n",
@@ -2655,7 +2654,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
 			if (test_opt(sb, ERRORS_PANIC)) {
 				EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS;
 				es->s_state |= cpu_to_le16(EXT4_ERROR_FS);
-				ext4_commit_super(sb, es, 1);
+				ext4_commit_super(sb, 1);
 				goto failed_mount4;
 			}
 		}
@@ -3132,15 +3131,15 @@ static int ext4_load_journal(struct super_block *sb,
 		sb->s_dirt = 1;
 
 		/* Make sure we flush the recovery flag to disk. */
-		ext4_commit_super(sb, es, 1);
+		ext4_commit_super(sb, 1);
 	}
 
 	return 0;
 }
 
-static int ext4_commit_super(struct super_block *sb,
-			      struct ext4_super_block *es, int sync)
+static int ext4_commit_super(struct super_block *sb, int sync)
 {
+	struct ext4_super_block *es = EXT4_SB(sb)->s_es;
 	struct buffer_head *sbh = EXT4_SB(sb)->s_sbh;
 	int error = 0;
 
@@ -3212,7 +3211,7 @@ static void ext4_mark_recovery_complete(struct super_block *sb,
 	    sb->s_flags & MS_RDONLY) {
 		EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
 		sb->s_dirt = 0;
-		ext4_commit_super(sb, es, 1);
+		ext4_commit_super(sb, 1);
 	}
 	unlock_super(sb);
 
@@ -3253,7 +3252,7 @@ static void ext4_clear_journal_err(struct super_block *sb,
 
 		EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS;
 		es->s_state |= cpu_to_le16(EXT4_ERROR_FS);
-		ext4_commit_super(sb, es, 1);
+		ext4_commit_super(sb, 1);
 
 		jbd2_journal_clear_err(journal);
 	}
@@ -3293,7 +3292,7 @@ static void ext4_write_super(struct super_block *sb)
 			BUG();
 		sb->s_dirt = 0;
 	} else {
-		ext4_commit_super(sb, EXT4_SB(sb)->s_es, 1);
+		ext4_commit_super(sb, 1);
 	}
 }
 
@@ -3312,7 +3311,7 @@ static int ext4_sync_fs(struct super_block *sb, int wait)
 						     target);
 		}
 	} else {
-		ext4_commit_super(sb, EXT4_SB(sb)->s_es, wait);
+		ext4_commit_super(sb, wait);
 	}
 	return ret;
 }
@@ -3345,7 +3344,7 @@ static int ext4_freeze(struct super_block *sb)
 
 		/* Journal blocked and flushed, clear needs_recovery flag. */
 		EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
-		error = ext4_commit_super(sb, EXT4_SB(sb)->s_es, 1);
+		error = ext4_commit_super(sb, 1);
 		if (error)
 			goto out;
 	}
@@ -3365,7 +3364,7 @@ static int ext4_unfreeze(struct super_block *sb)
 		lock_super(sb);
 		/* Reser the needs_recovery flag before the fs is unlocked. */
 		EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
-		ext4_commit_super(sb, EXT4_SB(sb)->s_es, 1);
+		ext4_commit_super(sb, 1);
 		unlock_super(sb);
 		jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal);
 	}
@@ -3520,7 +3519,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
 		}
 	}
 	if (sbi->s_journal == NULL)
-		ext4_commit_super(sb, es, 1);
+		ext4_commit_super(sb, 1);
 
 #ifdef CONFIG_QUOTA
 	/* Release old quota file names */
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 2/3] ext4: Fix and simplify s_dirt handling
  2009-05-01  4:37 [PATCH 1/3] ext4: Simplify ext4_commit_super()'s function signature Theodore Ts'o
@ 2009-05-01  4:37 ` Theodore Ts'o
  2009-05-01  4:37   ` [PATCH 3/3] ext4: Use separate super_operations structure for no_journal filesystems Theodore Ts'o
  2009-05-01  7:02   ` [PATCH 2/3] ext4: Fix and simplify s_dirt handling Christoph Hellwig
  0 siblings, 2 replies; 12+ messages in thread
From: Theodore Ts'o @ 2009-05-01  4:37 UTC (permalink / raw)
  To: Ext4 Developers List; +Cc: Theodore Ts'o

The s_dirt flag wasn't completely handled correctly, but it didn't
really matter when journalling was enabled.  It turns out that when
ext4 runs without a journal, we don't clear s_dirt in places where we
should have, with the result that the high-level write_super()
function was writing the superblock when it wasn't necessary.

So we fix this by making ext4_commit_super() clear the s_dirt flag,
and removing many of the other places where s_dirt is manipulated.
When journalling is enabled, the s_dirt flag might be left set more
often, but s_dirt really doesn't matter when journalling is enabled.

Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
---
 fs/ext4/super.c |   14 +++-----------
 1 files changed, 3 insertions(+), 11 deletions(-)

diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index ad4c9be..7c7a08a 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -3128,7 +3128,6 @@ static int ext4_load_journal(struct super_block *sb,
 	if (journal_devnum &&
 	    journal_devnum != le32_to_cpu(es->s_journal_dev)) {
 		es->s_journal_dev = cpu_to_le32(journal_devnum);
-		sb->s_dirt = 1;
 
 		/* Make sure we flush the recovery flag to disk. */
 		ext4_commit_super(sb, 1);
@@ -3168,7 +3167,7 @@ static int ext4_commit_super(struct super_block *sb, int sync)
 					&EXT4_SB(sb)->s_freeblocks_counter));
 	es->s_free_inodes_count = cpu_to_le32(percpu_counter_sum_positive(
 					&EXT4_SB(sb)->s_freeinodes_counter));
-
+	sb->s_dirt = 0;
 	BUFFER_TRACE(sbh, "marking dirty");
 	mark_buffer_dirty(sbh);
 	if (sync) {
@@ -3210,7 +3209,6 @@ static void ext4_mark_recovery_complete(struct super_block *sb,
 	if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER) &&
 	    sb->s_flags & MS_RDONLY) {
 		EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
-		sb->s_dirt = 0;
 		ext4_commit_super(sb, 1);
 	}
 	unlock_super(sb);
@@ -3271,10 +3269,8 @@ int ext4_force_commit(struct super_block *sb)
 		return 0;
 
 	journal = EXT4_SB(sb)->s_journal;
-	if (journal) {
-		sb->s_dirt = 0;
+	if (journal)
 		ret = ext4_journal_force_commit(journal);
-	}
 
 	return ret;
 }
@@ -3282,15 +3278,13 @@ int ext4_force_commit(struct super_block *sb)
 /*
  * Ext4 always journals updates to the superblock itself, so we don't
  * have to propagate any other updates to the superblock on disk at this
- * point.  (We can probably nuke this function altogether, and remove
- * any mention to sb->s_dirt in all of fs/ext4; eventual cleanup...)
+ * point if the journalling is enabled.
  */
 static void ext4_write_super(struct super_block *sb)
 {
 	if (EXT4_SB(sb)->s_journal) {
 		if (mutex_trylock(&sb->s_lock) != 0)
 			BUG();
-		sb->s_dirt = 0;
 	} else {
 		ext4_commit_super(sb, 1);
 	}
@@ -3302,7 +3296,6 @@ static int ext4_sync_fs(struct super_block *sb, int wait)
 	tid_t target;
 
 	trace_mark(ext4_sync_fs, "dev %s wait %d", sb->s_id, wait);
-	sb->s_dirt = 0;
 	if (EXT4_SB(sb)->s_journal) {
 		if (jbd2_journal_start_commit(EXT4_SB(sb)->s_journal,
 					      &target)) {
@@ -3324,7 +3317,6 @@ static int ext4_freeze(struct super_block *sb)
 {
 	int error = 0;
 	journal_t *journal;
-	sb->s_dirt = 0;
 
 	if (!(sb->s_flags & MS_RDONLY)) {
 		journal = EXT4_SB(sb)->s_journal;
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 3/3] ext4: Use separate super_operations structure for no_journal filesystems
  2009-05-01  4:37 ` [PATCH 2/3] ext4: Fix and simplify s_dirt handling Theodore Ts'o
@ 2009-05-01  4:37   ` Theodore Ts'o
  2009-05-01  7:04     ` Christoph Hellwig
  2009-05-01 10:42     ` Andreas Dilger
  2009-05-01  7:02   ` [PATCH 2/3] ext4: Fix and simplify s_dirt handling Christoph Hellwig
  1 sibling, 2 replies; 12+ messages in thread
From: Theodore Ts'o @ 2009-05-01  4:37 UTC (permalink / raw)
  To: Ext4 Developers List; +Cc: Theodore Ts'o

By using a separate super_operations structure for filesystems that
have and don't have journals, we can simply ext4_write_super() ---
which is only needed when no journal is present --- and ext4_freeze(),
ext4_unfreeze(), and ext4_sync_fs(), which are only needed when the
journal is present.

Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
---
 fs/ext4/super.c |   98 ++++++++++++++++++++++++++-----------------------------
 1 files changed, 46 insertions(+), 52 deletions(-)

diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 7c7a08a..241a81e 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -65,7 +65,6 @@ static const char *ext4_decode_error(struct super_block *sb, int errno,
 static int ext4_remount(struct super_block *sb, int *flags, char *data);
 static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf);
 static int ext4_unfreeze(struct super_block *sb);
-static void ext4_write_super(struct super_block *sb);
 static int ext4_freeze(struct super_block *sb);
 
 
@@ -995,7 +994,6 @@ static const struct super_operations ext4_sops = {
 	.dirty_inode	= ext4_dirty_inode,
 	.delete_inode	= ext4_delete_inode,
 	.put_super	= ext4_put_super,
-	.write_super	= ext4_write_super,
 	.sync_fs	= ext4_sync_fs,
 	.freeze_fs	= ext4_freeze,
 	.unfreeze_fs	= ext4_unfreeze,
@@ -1010,6 +1008,8 @@ static const struct super_operations ext4_sops = {
 	.bdev_try_to_free_page = bdev_try_to_free_page,
 };
 
+static struct super_operations ext4_nojournal_sops;
+
 static const struct export_operations ext4_export_ops = {
 	.fh_to_dentry = ext4_fh_to_dentry,
 	.fh_to_parent = ext4_fh_to_parent,
@@ -2615,7 +2615,11 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
 	/*
 	 * set up enough so that it can read an inode
 	 */
-	sb->s_op = &ext4_sops;
+	if (!test_opt(sb, NOLOAD) &&
+	    EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL))
+		sb->s_op = &ext4_sops;
+	else
+		sb->s_op = &ext4_nojournal_sops;
 	sb->s_export_op = &ext4_export_ops;
 	sb->s_xattr = ext4_xattr_handlers;
 #ifdef CONFIG_QUOTA
@@ -3275,19 +3279,9 @@ int ext4_force_commit(struct super_block *sb)
 	return ret;
 }
 
-/*
- * Ext4 always journals updates to the superblock itself, so we don't
- * have to propagate any other updates to the superblock on disk at this
- * point if the journalling is enabled.
- */
 static void ext4_write_super(struct super_block *sb)
 {
-	if (EXT4_SB(sb)->s_journal) {
-		if (mutex_trylock(&sb->s_lock) != 0)
-			BUG();
-	} else {
-		ext4_commit_super(sb, 1);
-	}
+	ext4_commit_super(sb, 1);
 }
 
 static int ext4_sync_fs(struct super_block *sb, int wait)
@@ -3296,15 +3290,9 @@ static int ext4_sync_fs(struct super_block *sb, int wait)
 	tid_t target;
 
 	trace_mark(ext4_sync_fs, "dev %s wait %d", sb->s_id, wait);
-	if (EXT4_SB(sb)->s_journal) {
-		if (jbd2_journal_start_commit(EXT4_SB(sb)->s_journal,
-					      &target)) {
-			if (wait)
-				jbd2_log_wait_commit(EXT4_SB(sb)->s_journal,
-						     target);
-		}
-	} else {
-		ext4_commit_super(sb, wait);
+	if (jbd2_journal_start_commit(EXT4_SB(sb)->s_journal, &target)) {
+		if (wait)
+			jbd2_log_wait_commit(EXT4_SB(sb)->s_journal, target);
 	}
 	return ret;
 }
@@ -3318,32 +3306,31 @@ static int ext4_freeze(struct super_block *sb)
 	int error = 0;
 	journal_t *journal;
 
-	if (!(sb->s_flags & MS_RDONLY)) {
-		journal = EXT4_SB(sb)->s_journal;
+	if (sb->s_flags & MS_RDONLY)
+		return 0;
 
-		if (journal) {
-			/* Now we set up the journal barrier. */
-			jbd2_journal_lock_updates(journal);
+	journal = EXT4_SB(sb)->s_journal;
 
-			/*
-			 * We don't want to clear needs_recovery flag when we
-			 * failed to flush the journal.
-			 */
-			error = jbd2_journal_flush(journal);
-			if (error < 0)
-				goto out;
-		}
+	/* Now we set up the journal barrier. */
+	jbd2_journal_lock_updates(journal);
 
-		/* Journal blocked and flushed, clear needs_recovery flag. */
-		EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
-		error = ext4_commit_super(sb, 1);
-		if (error)
-			goto out;
+	/*
+	 * Don't clear the needs_recovery flag if we failed to flush
+	 * the journal.
+	 */
+	error = jbd2_journal_flush(journal);
+	if (error < 0) {
+	out:
+		jbd2_journal_unlock_updates(journal);
+		return error;
 	}
+
+	/* Journal blocked and flushed, clear needs_recovery flag. */
+	EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
+	error = ext4_commit_super(sb, 1);
+	if (error)
+		goto out;
 	return 0;
-out:
-	jbd2_journal_unlock_updates(journal);
-	return error;
 }
 
 /*
@@ -3352,14 +3339,15 @@ out:
  */
 static int ext4_unfreeze(struct super_block *sb)
 {
-	if (EXT4_SB(sb)->s_journal && !(sb->s_flags & MS_RDONLY)) {
-		lock_super(sb);
-		/* Reser the needs_recovery flag before the fs is unlocked. */
-		EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
-		ext4_commit_super(sb, 1);
-		unlock_super(sb);
-		jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal);
-	}
+	if (sb->s_flags & MS_RDONLY)
+		return 0;
+
+	lock_super(sb);
+	/* Reset the needs_recovery flag before the fs is unlocked. */
+	EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
+	ext4_commit_super(sb, 1);
+	unlock_super(sb);
+	jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal);
 	return 0;
 }
 
@@ -3923,6 +3911,12 @@ static int __init init_ext4_fs(void)
 {
 	int err;
 
+	ext4_nojournal_sops = ext4_sops;
+	ext4_nojournal_sops.write_super = ext4_write_super;
+	ext4_nojournal_sops.sync_fs = 0;
+	ext4_nojournal_sops.freeze_fs = 0;
+	ext4_nojournal_sops.unfreeze_fs = 0;
+
 	ext4_kset = kset_create_and_add("ext4", NULL, fs_kobj);
 	if (!ext4_kset)
 		return -ENOMEM;
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/3] ext4: Fix and simplify s_dirt handling
  2009-05-01  4:37 ` [PATCH 2/3] ext4: Fix and simplify s_dirt handling Theodore Ts'o
  2009-05-01  4:37   ` [PATCH 3/3] ext4: Use separate super_operations structure for no_journal filesystems Theodore Ts'o
@ 2009-05-01  7:02   ` Christoph Hellwig
  2009-05-01 13:45     ` Theodore Tso
  1 sibling, 1 reply; 12+ messages in thread
From: Christoph Hellwig @ 2009-05-01  7:02 UTC (permalink / raw)
  To: Theodore Ts'o; +Cc: Ext4 Developers List

On Fri, May 01, 2009 at 12:37:16AM -0400, Theodore Ts'o wrote:
> The s_dirt flag wasn't completely handled correctly, but it didn't
> really matter when journalling was enabled.  It turns out that when
> ext4 runs without a journal, we don't clear s_dirt in places where we
> should have, with the result that the high-level write_super()
> function was writing the superblock when it wasn't necessary.
> 
> So we fix this by making ext4_commit_super() clear the s_dirt flag,
> and removing many of the other places where s_dirt is manipulated.
> When journalling is enabled, the s_dirt flag might be left set more
> often, but s_dirt really doesn't matter when journalling is enabled.

Btw, you might want to move all s_dirt setting into a wrapper, so that
it never gets set for journal mode.  That way we can avoid superflous
calls into the filesystem in that default mode.


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 3/3] ext4: Use separate super_operations structure for no_journal filesystems
  2009-05-01  4:37   ` [PATCH 3/3] ext4: Use separate super_operations structure for no_journal filesystems Theodore Ts'o
@ 2009-05-01  7:04     ` Christoph Hellwig
  2009-05-01 13:48       ` Theodore Tso
  2009-05-01 10:42     ` Andreas Dilger
  1 sibling, 1 reply; 12+ messages in thread
From: Christoph Hellwig @ 2009-05-01  7:04 UTC (permalink / raw)
  To: Theodore Ts'o; +Cc: Ext4 Developers List

On Fri, May 01, 2009 at 12:37:17AM -0400, Theodore Ts'o wrote:
> By using a separate super_operations structure for filesystems that
> have and don't have journals, we can simply ext4_write_super() ---
> which is only needed when no journal is present --- and ext4_freeze(),
> ext4_unfreeze(), and ext4_sync_fs(), which are only needed when the
> journal is present.

FYI: I will make ->sync_fs mandatory pretty soon.  At that point
->write_super will only be left for d_dirt-induced periodic writeback.
(Still have to figure out what to do about file_fsync, but that won't
affect ext4)


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 3/3] ext4: Use separate super_operations structure for no_journal filesystems
  2009-05-01  4:37   ` [PATCH 3/3] ext4: Use separate super_operations structure for no_journal filesystems Theodore Ts'o
  2009-05-01  7:04     ` Christoph Hellwig
@ 2009-05-01 10:42     ` Andreas Dilger
  2009-05-01 13:49       ` Theodore Tso
                         ` (2 more replies)
  1 sibling, 3 replies; 12+ messages in thread
From: Andreas Dilger @ 2009-05-01 10:42 UTC (permalink / raw)
  To: Theodore Ts'o; +Cc: Ext4 Developers List

On May 01, 2009  00:37 -0400, Theodore Ts'o wrote:
> @@ -3923,6 +3911,12 @@ static int __init init_ext4_fs(void)
> +	ext4_nojournal_sops = ext4_sops;
> +	ext4_nojournal_sops.write_super = ext4_write_super;
> +	ext4_nojournal_sops.sync_fs = 0;
> +	ext4_nojournal_sops.freeze_fs = 0;
> +	ext4_nojournal_sops.unfreeze_fs = 0;

I thought the general policy these days was to make a static const
ops struct so that it cannot be changed (correctly or incorrectly)?

Cheers, Andreas
--
Andreas Dilger
Sr. Staff Engineer, Lustre Group
Sun Microsystems of Canada, Inc.


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/3] ext4: Fix and simplify s_dirt handling
  2009-05-01  7:02   ` [PATCH 2/3] ext4: Fix and simplify s_dirt handling Christoph Hellwig
@ 2009-05-01 13:45     ` Theodore Tso
  0 siblings, 0 replies; 12+ messages in thread
From: Theodore Tso @ 2009-05-01 13:45 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: Ext4 Developers List

On Fri, May 01, 2009 at 03:02:55AM -0400, Christoph Hellwig wrote:
> On Fri, May 01, 2009 at 12:37:16AM -0400, Theodore Ts'o wrote:
> > The s_dirt flag wasn't completely handled correctly, but it didn't
> > really matter when journalling was enabled.  It turns out that when
> > ext4 runs without a journal, we don't clear s_dirt in places where we
> > should have, with the result that the high-level write_super()
> > function was writing the superblock when it wasn't necessary.
> > 
> > So we fix this by making ext4_commit_super() clear the s_dirt flag,
> > and removing many of the other places where s_dirt is manipulated.
> > When journalling is enabled, the s_dirt flag might be left set more
> > often, but s_dirt really doesn't matter when journalling is enabled.
> 
> Btw, you might want to move all s_dirt setting into a wrapper, so that
> it never gets set for journal mode.  That way we can avoid superflous
> calls into the filesystem in that default mode.

I thought about doing this, but currently the VFS core checks for the
presence for the write_super method function before it checks for
s_dirt, so it didn't seem to matter much whether or not s_dirt was set
if the filesystem doesn't have a NULL write_super function.

       		  	       	      - Ted

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 3/3] ext4: Use separate super_operations structure for no_journal filesystems
  2009-05-01  7:04     ` Christoph Hellwig
@ 2009-05-01 13:48       ` Theodore Tso
  2009-05-01 14:24         ` Christoph Hellwig
  0 siblings, 1 reply; 12+ messages in thread
From: Theodore Tso @ 2009-05-01 13:48 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: Ext4 Developers List

On Fri, May 01, 2009 at 03:04:22AM -0400, Christoph Hellwig wrote:
> On Fri, May 01, 2009 at 12:37:17AM -0400, Theodore Ts'o wrote:
> > By using a separate super_operations structure for filesystems that
> > have and don't have journals, we can simply ext4_write_super() ---
> > which is only needed when no journal is present --- and ext4_freeze(),
> > ext4_unfreeze(), and ext4_sync_fs(), which are only needed when the
> > journal is present.
> 
> FYI: I will make ->sync_fs mandatory pretty soon.  At that point
> ->write_super will only be left for d_dirt-induced periodic writeback.
> (Still have to figure out what to do about file_fsync, but that won't
> affect ext4)

So I'm guessing your plans are to have sys_sync() no longer call
write_super(), but to only call sync_fs()?  If that's the case, I
think all we need to do is set ext4_nojournal_sops.sync_fs to be
ext4_commit_super.

I assume the idea is so that the filesystem can distinguish between
periodic s_dirt writeback versus a request to write the superblock
caused by an explicit fsync or sync system call?

						- Ted

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 3/3] ext4: Use separate super_operations structure for no_journal filesystems
  2009-05-01 10:42     ` Andreas Dilger
@ 2009-05-01 13:49       ` Theodore Tso
  2009-05-01 14:47       ` Christoph Hellwig
  2009-05-01 16:55       ` [PATCH v2] " Theodore Ts'o
  2 siblings, 0 replies; 12+ messages in thread
From: Theodore Tso @ 2009-05-01 13:49 UTC (permalink / raw)
  To: Andreas Dilger; +Cc: Ext4 Developers List

On Fri, May 01, 2009 at 04:42:53AM -0600, Andreas Dilger wrote:
> On May 01, 2009  00:37 -0400, Theodore Ts'o wrote:
> > @@ -3923,6 +3911,12 @@ static int __init init_ext4_fs(void)
> > +	ext4_nojournal_sops = ext4_sops;
> > +	ext4_nojournal_sops.write_super = ext4_write_super;
> > +	ext4_nojournal_sops.sync_fs = 0;
> > +	ext4_nojournal_sops.freeze_fs = 0;
> > +	ext4_nojournal_sops.unfreeze_fs = 0;
> 
> I thought the general policy these days was to make a static const
> ops struct so that it cannot be changed (correctly or incorrectly)?

The tradeoff is this makes it much easier from a maintenance point of
view to see what the differences are between ext4_nojournal_sops and
ext4_journal_sops.

						- Ted

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 3/3] ext4: Use separate super_operations structure for no_journal filesystems
  2009-05-01 13:48       ` Theodore Tso
@ 2009-05-01 14:24         ` Christoph Hellwig
  0 siblings, 0 replies; 12+ messages in thread
From: Christoph Hellwig @ 2009-05-01 14:24 UTC (permalink / raw)
  To: Theodore Tso; +Cc: Christoph Hellwig, Ext4 Developers List

On Fri, May 01, 2009 at 09:48:04AM -0400, Theodore Tso wrote:
> So I'm guessing your plans are to have sys_sync() no longer call
> write_super(), but to only call sync_fs()?  If that's the case, I
> think all we need to do is set ext4_nojournal_sops.sync_fs to be
> ext4_commit_super.
> 
> I assume the idea is so that the filesystem can distinguish between
> periodic s_dirt writeback versus a request to write the superblock
> caused by an explicit fsync or sync system call?

Exactly.  The plan is to use write_super only for peridoic writeback,
everything that is used for data integrity will go through ->sync_fs.

We'll grow a couple more ->sync_fs instances, but I think the result
is a lot more logic.  We'll also avoid the mostly useless double
sb writes due to ->write_super being called for both the wait = 0 and
wait = 1 cases in sync.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 3/3] ext4: Use separate super_operations structure for no_journal filesystems
  2009-05-01 10:42     ` Andreas Dilger
  2009-05-01 13:49       ` Theodore Tso
@ 2009-05-01 14:47       ` Christoph Hellwig
  2009-05-01 16:55       ` [PATCH v2] " Theodore Ts'o
  2 siblings, 0 replies; 12+ messages in thread
From: Christoph Hellwig @ 2009-05-01 14:47 UTC (permalink / raw)
  To: Andreas Dilger; +Cc: Theodore Ts'o, Ext4 Developers List

On Fri, May 01, 2009 at 04:42:53AM -0600, Andreas Dilger wrote:
> On May 01, 2009  00:37 -0400, Theodore Ts'o wrote:
> > @@ -3923,6 +3911,12 @@ static int __init init_ext4_fs(void)
> > +	ext4_nojournal_sops = ext4_sops;
> > +	ext4_nojournal_sops.write_super = ext4_write_super;
> > +	ext4_nojournal_sops.sync_fs = 0;
> > +	ext4_nojournal_sops.freeze_fs = 0;
> > +	ext4_nojournal_sops.unfreeze_fs = 0;
> 
> I thought the general policy these days was to make a static const
> ops struct so that it cannot be changed (correctly or incorrectly)?

Yeah.  Having the super ops in the normal style would be a lot more
readable.  We don't copy mostly the same inode or file operations
either.

And to be super-pedantic NULL pointer should be initialized as NULL, not
0.


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v2] ext4: Use separate super_operations structure for no_journal filesystems
  2009-05-01 10:42     ` Andreas Dilger
  2009-05-01 13:49       ` Theodore Tso
  2009-05-01 14:47       ` Christoph Hellwig
@ 2009-05-01 16:55       ` Theodore Ts'o
  2 siblings, 0 replies; 12+ messages in thread
From: Theodore Ts'o @ 2009-05-01 16:55 UTC (permalink / raw)
  To: Ext4 Developers List; +Cc: Andreas Dilger, Theodore Ts'o

By using a separate super_operations structure for filesystems that
have and don't have journals, we can simply ext4_write_super() ---
which is only needed when no journal is present --- and ext4_freeze(),
ext4_unfreeze(), and ext4_sync_fs(), which are only needed when the
journal is present.

Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
---
 fs/ext4/super.c |  108 +++++++++++++++++++++++++++++--------------------------
 1 files changed, 57 insertions(+), 51 deletions(-)

diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 7c7a08a..68c3a44 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -995,7 +995,6 @@ static const struct super_operations ext4_sops = {
 	.dirty_inode	= ext4_dirty_inode,
 	.delete_inode	= ext4_delete_inode,
 	.put_super	= ext4_put_super,
-	.write_super	= ext4_write_super,
 	.sync_fs	= ext4_sync_fs,
 	.freeze_fs	= ext4_freeze,
 	.unfreeze_fs	= ext4_unfreeze,
@@ -1010,6 +1009,25 @@ static const struct super_operations ext4_sops = {
 	.bdev_try_to_free_page = bdev_try_to_free_page,
 };
 
+static const struct super_operations ext4_nojournal_sops = {
+	.alloc_inode	= ext4_alloc_inode,
+	.destroy_inode	= ext4_destroy_inode,
+	.write_inode	= ext4_write_inode,
+	.dirty_inode	= ext4_dirty_inode,
+	.delete_inode	= ext4_delete_inode,
+	.write_super	= ext4_write_super,
+	.put_super	= ext4_put_super,
+	.statfs		= ext4_statfs,
+	.remount_fs	= ext4_remount,
+	.clear_inode	= ext4_clear_inode,
+	.show_options	= ext4_show_options,
+#ifdef CONFIG_QUOTA
+	.quota_read	= ext4_quota_read,
+	.quota_write	= ext4_quota_write,
+#endif
+	.bdev_try_to_free_page = bdev_try_to_free_page,
+};
+
 static const struct export_operations ext4_export_ops = {
 	.fh_to_dentry = ext4_fh_to_dentry,
 	.fh_to_parent = ext4_fh_to_parent,
@@ -2615,7 +2633,11 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
 	/*
 	 * set up enough so that it can read an inode
 	 */
-	sb->s_op = &ext4_sops;
+	if (!test_opt(sb, NOLOAD) &&
+	    EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL))
+		sb->s_op = &ext4_sops;
+	else
+		sb->s_op = &ext4_nojournal_sops;
 	sb->s_export_op = &ext4_export_ops;
 	sb->s_xattr = ext4_xattr_handlers;
 #ifdef CONFIG_QUOTA
@@ -3275,19 +3297,9 @@ int ext4_force_commit(struct super_block *sb)
 	return ret;
 }
 
-/*
- * Ext4 always journals updates to the superblock itself, so we don't
- * have to propagate any other updates to the superblock on disk at this
- * point if the journalling is enabled.
- */
 static void ext4_write_super(struct super_block *sb)
 {
-	if (EXT4_SB(sb)->s_journal) {
-		if (mutex_trylock(&sb->s_lock) != 0)
-			BUG();
-	} else {
-		ext4_commit_super(sb, 1);
-	}
+	ext4_commit_super(sb, 1);
 }
 
 static int ext4_sync_fs(struct super_block *sb, int wait)
@@ -3296,15 +3308,9 @@ static int ext4_sync_fs(struct super_block *sb, int wait)
 	tid_t target;
 
 	trace_mark(ext4_sync_fs, "dev %s wait %d", sb->s_id, wait);
-	if (EXT4_SB(sb)->s_journal) {
-		if (jbd2_journal_start_commit(EXT4_SB(sb)->s_journal,
-					      &target)) {
-			if (wait)
-				jbd2_log_wait_commit(EXT4_SB(sb)->s_journal,
-						     target);
-		}
-	} else {
-		ext4_commit_super(sb, wait);
+	if (jbd2_journal_start_commit(EXT4_SB(sb)->s_journal, &target)) {
+		if (wait)
+			jbd2_log_wait_commit(EXT4_SB(sb)->s_journal, target);
 	}
 	return ret;
 }
@@ -3318,32 +3324,31 @@ static int ext4_freeze(struct super_block *sb)
 	int error = 0;
 	journal_t *journal;
 
-	if (!(sb->s_flags & MS_RDONLY)) {
-		journal = EXT4_SB(sb)->s_journal;
+	if (sb->s_flags & MS_RDONLY)
+		return 0;
 
-		if (journal) {
-			/* Now we set up the journal barrier. */
-			jbd2_journal_lock_updates(journal);
+	journal = EXT4_SB(sb)->s_journal;
 
-			/*
-			 * We don't want to clear needs_recovery flag when we
-			 * failed to flush the journal.
-			 */
-			error = jbd2_journal_flush(journal);
-			if (error < 0)
-				goto out;
-		}
+	/* Now we set up the journal barrier. */
+	jbd2_journal_lock_updates(journal);
 
-		/* Journal blocked and flushed, clear needs_recovery flag. */
-		EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
-		error = ext4_commit_super(sb, 1);
-		if (error)
-			goto out;
+	/*
+	 * Don't clear the needs_recovery flag if we failed to flush
+	 * the journal.
+	 */
+	error = jbd2_journal_flush(journal);
+	if (error < 0) {
+	out:
+		jbd2_journal_unlock_updates(journal);
+		return error;
 	}
+
+	/* Journal blocked and flushed, clear needs_recovery flag. */
+	EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
+	error = ext4_commit_super(sb, 1);
+	if (error)
+		goto out;
 	return 0;
-out:
-	jbd2_journal_unlock_updates(journal);
-	return error;
 }
 
 /*
@@ -3352,14 +3357,15 @@ out:
  */
 static int ext4_unfreeze(struct super_block *sb)
 {
-	if (EXT4_SB(sb)->s_journal && !(sb->s_flags & MS_RDONLY)) {
-		lock_super(sb);
-		/* Reser the needs_recovery flag before the fs is unlocked. */
-		EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
-		ext4_commit_super(sb, 1);
-		unlock_super(sb);
-		jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal);
-	}
+	if (sb->s_flags & MS_RDONLY)
+		return 0;
+
+	lock_super(sb);
+	/* Reset the needs_recovery flag before the fs is unlocked. */
+	EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
+	ext4_commit_super(sb, 1);
+	unlock_super(sb);
+	jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal);
 	return 0;
 }
 
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2009-05-01 16:56 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-05-01  4:37 [PATCH 1/3] ext4: Simplify ext4_commit_super()'s function signature Theodore Ts'o
2009-05-01  4:37 ` [PATCH 2/3] ext4: Fix and simplify s_dirt handling Theodore Ts'o
2009-05-01  4:37   ` [PATCH 3/3] ext4: Use separate super_operations structure for no_journal filesystems Theodore Ts'o
2009-05-01  7:04     ` Christoph Hellwig
2009-05-01 13:48       ` Theodore Tso
2009-05-01 14:24         ` Christoph Hellwig
2009-05-01 10:42     ` Andreas Dilger
2009-05-01 13:49       ` Theodore Tso
2009-05-01 14:47       ` Christoph Hellwig
2009-05-01 16:55       ` [PATCH v2] " Theodore Ts'o
2009-05-01  7:02   ` [PATCH 2/3] ext4: Fix and simplify s_dirt handling Christoph Hellwig
2009-05-01 13:45     ` Theodore Tso

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).