diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-06-01 13:12:15 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-06-01 13:12:15 -0400 |
commit | 4edebed86690eb8db9af3ab85baf4a34e73266cc (patch) | |
tree | 8ab144b08f490f239fa62be52470860c9311664d /fs/ext4/mmp.c | |
parent | 51eab603f5c86dd1eae4c525df3e7f7eeab401d6 (diff) | |
parent | 5e44f8c374dc4f8eadf61cd18b2c0d46bc87c1b7 (diff) |
Merge tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
Pull Ext4 updates from Theodore Ts'o:
"The major new feature added in this update is Darrick J Wong's
metadata checksum feature, which adds crc32 checksums to ext4's
metadata fields.
There is also the usual set of cleanups and bug fixes."
* tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: (44 commits)
ext4: hole-punch use truncate_pagecache_range
jbd2: use kmem_cache_zalloc wrapper instead of flag
ext4: remove mb_groups before tearing down the buddy_cache
ext4: add ext4_mb_unload_buddy in the error path
ext4: don't trash state flags in EXT4_IOC_SETFLAGS
ext4: let getattr report the right blocks in delalloc+bigalloc
ext4: add missing save_error_info() to ext4_error()
ext4: add debugging trigger for ext4_error()
ext4: protect group inode free counting with group lock
ext4: use consistent ssize_t type in ext4_file_write()
ext4: fix format flag in ext4_ext_binsearch_idx()
ext4: cleanup in ext4_discard_allocated_blocks()
ext4: return ENOMEM when mounts fail due to lack of memory
ext4: remove redundundant "(char *) bh->b_data" casts
ext4: disallow hard-linked directory in ext4_lookup
ext4: fix potential integer overflow in alloc_flex_gd()
ext4: remove needs_recovery in ext4_mb_init()
ext4: force ro mount if ext4_setup_super() fails
ext4: fix potential NULL dereference in ext4_free_inodes_counts()
ext4/jbd2: add metadata checksumming to the list of supported features
...
Diffstat (limited to 'fs/ext4/mmp.c')
-rw-r--r-- | fs/ext4/mmp.c | 44 |
1 files changed, 39 insertions, 5 deletions
diff --git a/fs/ext4/mmp.c b/fs/ext4/mmp.c index ed6548d89165..f99a1311e847 100644 --- a/fs/ext4/mmp.c +++ b/fs/ext4/mmp.c | |||
@@ -6,12 +6,45 @@ | |||
6 | 6 | ||
7 | #include "ext4.h" | 7 | #include "ext4.h" |
8 | 8 | ||
9 | /* Checksumming functions */ | ||
10 | static __u32 ext4_mmp_csum(struct super_block *sb, struct mmp_struct *mmp) | ||
11 | { | ||
12 | struct ext4_sb_info *sbi = EXT4_SB(sb); | ||
13 | int offset = offsetof(struct mmp_struct, mmp_checksum); | ||
14 | __u32 csum; | ||
15 | |||
16 | csum = ext4_chksum(sbi, sbi->s_csum_seed, (char *)mmp, offset); | ||
17 | |||
18 | return cpu_to_le32(csum); | ||
19 | } | ||
20 | |||
21 | int ext4_mmp_csum_verify(struct super_block *sb, struct mmp_struct *mmp) | ||
22 | { | ||
23 | if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, | ||
24 | EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) | ||
25 | return 1; | ||
26 | |||
27 | return mmp->mmp_checksum == ext4_mmp_csum(sb, mmp); | ||
28 | } | ||
29 | |||
30 | void ext4_mmp_csum_set(struct super_block *sb, struct mmp_struct *mmp) | ||
31 | { | ||
32 | if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, | ||
33 | EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) | ||
34 | return; | ||
35 | |||
36 | mmp->mmp_checksum = ext4_mmp_csum(sb, mmp); | ||
37 | } | ||
38 | |||
9 | /* | 39 | /* |
10 | * Write the MMP block using WRITE_SYNC to try to get the block on-disk | 40 | * Write the MMP block using WRITE_SYNC to try to get the block on-disk |
11 | * faster. | 41 | * faster. |
12 | */ | 42 | */ |
13 | static int write_mmp_block(struct buffer_head *bh) | 43 | static int write_mmp_block(struct super_block *sb, struct buffer_head *bh) |
14 | { | 44 | { |
45 | struct mmp_struct *mmp = (struct mmp_struct *)(bh->b_data); | ||
46 | |||
47 | ext4_mmp_csum_set(sb, mmp); | ||
15 | mark_buffer_dirty(bh); | 48 | mark_buffer_dirty(bh); |
16 | lock_buffer(bh); | 49 | lock_buffer(bh); |
17 | bh->b_end_io = end_buffer_write_sync; | 50 | bh->b_end_io = end_buffer_write_sync; |
@@ -59,7 +92,8 @@ static int read_mmp_block(struct super_block *sb, struct buffer_head **bh, | |||
59 | } | 92 | } |
60 | 93 | ||
61 | mmp = (struct mmp_struct *)((*bh)->b_data); | 94 | mmp = (struct mmp_struct *)((*bh)->b_data); |
62 | if (le32_to_cpu(mmp->mmp_magic) != EXT4_MMP_MAGIC) | 95 | if (le32_to_cpu(mmp->mmp_magic) != EXT4_MMP_MAGIC || |
96 | !ext4_mmp_csum_verify(sb, mmp)) | ||
63 | return -EINVAL; | 97 | return -EINVAL; |
64 | 98 | ||
65 | return 0; | 99 | return 0; |
@@ -120,7 +154,7 @@ static int kmmpd(void *data) | |||
120 | mmp->mmp_time = cpu_to_le64(get_seconds()); | 154 | mmp->mmp_time = cpu_to_le64(get_seconds()); |
121 | last_update_time = jiffies; | 155 | last_update_time = jiffies; |
122 | 156 | ||
123 | retval = write_mmp_block(bh); | 157 | retval = write_mmp_block(sb, bh); |
124 | /* | 158 | /* |
125 | * Don't spew too many error messages. Print one every | 159 | * Don't spew too many error messages. Print one every |
126 | * (s_mmp_update_interval * 60) seconds. | 160 | * (s_mmp_update_interval * 60) seconds. |
@@ -200,7 +234,7 @@ static int kmmpd(void *data) | |||
200 | mmp->mmp_seq = cpu_to_le32(EXT4_MMP_SEQ_CLEAN); | 234 | mmp->mmp_seq = cpu_to_le32(EXT4_MMP_SEQ_CLEAN); |
201 | mmp->mmp_time = cpu_to_le64(get_seconds()); | 235 | mmp->mmp_time = cpu_to_le64(get_seconds()); |
202 | 236 | ||
203 | retval = write_mmp_block(bh); | 237 | retval = write_mmp_block(sb, bh); |
204 | 238 | ||
205 | failed: | 239 | failed: |
206 | kfree(data); | 240 | kfree(data); |
@@ -299,7 +333,7 @@ skip: | |||
299 | seq = mmp_new_seq(); | 333 | seq = mmp_new_seq(); |
300 | mmp->mmp_seq = cpu_to_le32(seq); | 334 | mmp->mmp_seq = cpu_to_le32(seq); |
301 | 335 | ||
302 | retval = write_mmp_block(bh); | 336 | retval = write_mmp_block(sb, bh); |
303 | if (retval) | 337 | if (retval) |
304 | goto failed; | 338 | goto failed; |
305 | 339 | ||