diff options
author | Girish Shilamkar <girish@clusterfs.com> | 2008-01-28 23:58:27 -0500 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2008-01-28 23:58:27 -0500 |
commit | 818d276ceb83aa9fdebb5e0a53188290312de987 (patch) | |
tree | de3fb4ffadd72caea2876c5232ce76cd14b3646e /fs/ext4/super.c | |
parent | 8e85fb3f305b24b79c6d9cb7a56d22b062335ad3 (diff) |
ext4: Add the journal checksum feature
The journal checksum feature adds two new flags i.e
JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT and JBD2_FEATURE_COMPAT_CHECKSUM.
JBD2_FEATURE_CHECKSUM flag indicates that the commit block contains the
checksum for the blocks described by the descriptor blocks.
Due to checksums, writing of the commit record no longer needs to be
synchronous. Now commit record can be sent to disk without waiting for
descriptor blocks to be written to disk. This behavior is controlled
using JBD2_FEATURE_ASYNC_COMMIT flag. Older kernels/e2fsck should not be
able to recover the journal with _ASYNC_COMMIT hence it is made
incompat.
The commit header has been extended to hold the checksum along with the
type of the checksum.
For recovery in pass scan checksums are verified to ensure the sanity
and completeness(in case of _ASYNC_COMMIT) of every transaction.
Signed-off-by: Andreas Dilger <adilger@clusterfs.com>
Signed-off-by: Girish Shilamkar <girish@clusterfs.com>
Signed-off-by: Dave Kleikamp <shaggy@linux.vnet.ibm.com>
Signed-off-by: Mingming Cao <cmm@us.ibm.com>
Diffstat (limited to 'fs/ext4/super.c')
-rw-r--r-- | fs/ext4/super.c | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index c7305443e100..f7479d30735e 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -869,6 +869,7 @@ enum { | |||
869 | Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl, | 869 | Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl, |
870 | Opt_reservation, Opt_noreservation, Opt_noload, Opt_nobh, Opt_bh, | 870 | Opt_reservation, Opt_noreservation, Opt_noload, Opt_nobh, Opt_bh, |
871 | Opt_commit, Opt_journal_update, Opt_journal_inum, Opt_journal_dev, | 871 | Opt_commit, Opt_journal_update, Opt_journal_inum, Opt_journal_dev, |
872 | Opt_journal_checksum, Opt_journal_async_commit, | ||
872 | Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback, | 873 | Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback, |
873 | Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota, | 874 | Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota, |
874 | Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota, | 875 | Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota, |
@@ -908,6 +909,8 @@ static match_table_t tokens = { | |||
908 | {Opt_journal_update, "journal=update"}, | 909 | {Opt_journal_update, "journal=update"}, |
909 | {Opt_journal_inum, "journal=%u"}, | 910 | {Opt_journal_inum, "journal=%u"}, |
910 | {Opt_journal_dev, "journal_dev=%u"}, | 911 | {Opt_journal_dev, "journal_dev=%u"}, |
912 | {Opt_journal_checksum, "journal_checksum"}, | ||
913 | {Opt_journal_async_commit, "journal_async_commit"}, | ||
911 | {Opt_abort, "abort"}, | 914 | {Opt_abort, "abort"}, |
912 | {Opt_data_journal, "data=journal"}, | 915 | {Opt_data_journal, "data=journal"}, |
913 | {Opt_data_ordered, "data=ordered"}, | 916 | {Opt_data_ordered, "data=ordered"}, |
@@ -1095,6 +1098,13 @@ static int parse_options (char *options, struct super_block *sb, | |||
1095 | return 0; | 1098 | return 0; |
1096 | *journal_devnum = option; | 1099 | *journal_devnum = option; |
1097 | break; | 1100 | break; |
1101 | case Opt_journal_checksum: | ||
1102 | set_opt(sbi->s_mount_opt, JOURNAL_CHECKSUM); | ||
1103 | break; | ||
1104 | case Opt_journal_async_commit: | ||
1105 | set_opt(sbi->s_mount_opt, JOURNAL_ASYNC_COMMIT); | ||
1106 | set_opt(sbi->s_mount_opt, JOURNAL_CHECKSUM); | ||
1107 | break; | ||
1098 | case Opt_noload: | 1108 | case Opt_noload: |
1099 | set_opt (sbi->s_mount_opt, NOLOAD); | 1109 | set_opt (sbi->s_mount_opt, NOLOAD); |
1100 | break; | 1110 | break; |
@@ -2114,6 +2124,21 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent) | |||
2114 | goto failed_mount4; | 2124 | goto failed_mount4; |
2115 | } | 2125 | } |
2116 | 2126 | ||
2127 | if (test_opt(sb, JOURNAL_ASYNC_COMMIT)) { | ||
2128 | jbd2_journal_set_features(sbi->s_journal, | ||
2129 | JBD2_FEATURE_COMPAT_CHECKSUM, 0, | ||
2130 | JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT); | ||
2131 | } else if (test_opt(sb, JOURNAL_CHECKSUM)) { | ||
2132 | jbd2_journal_set_features(sbi->s_journal, | ||
2133 | JBD2_FEATURE_COMPAT_CHECKSUM, 0, 0); | ||
2134 | jbd2_journal_clear_features(sbi->s_journal, 0, 0, | ||
2135 | JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT); | ||
2136 | } else { | ||
2137 | jbd2_journal_clear_features(sbi->s_journal, | ||
2138 | JBD2_FEATURE_COMPAT_CHECKSUM, 0, | ||
2139 | JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT); | ||
2140 | } | ||
2141 | |||
2117 | /* We have now updated the journal if required, so we can | 2142 | /* We have now updated the journal if required, so we can |
2118 | * validate the data journaling mode. */ | 2143 | * validate the data journaling mode. */ |
2119 | switch (test_opt(sb, DATA_FLAGS)) { | 2144 | switch (test_opt(sb, DATA_FLAGS)) { |