forked from Minki/linux
jbd2: fix portability problems caused by unaligned accesses
This commit applies the e2fsck/recovery.c portions of commit 1e0c8ca7c08a ("e2fsck: fix portability problems caused by unaligned accesses) from the e2fsprogs git tree. The on-disk format for the ext4 journal can have unaigned 32-bit integers. This can happen when replaying a journal using a obsolete checksum format (which was never popularly used, since the v3 format replaced v2 while the metadata checksum feature was being stablized). Signed-off-by: Theodore Ts'o <tytso@mit.edu>
This commit is contained in:
parent
877ba3f729
commit
a20d1cebb9
@ -196,7 +196,7 @@ static int jbd2_descriptor_block_csum_verify(journal_t *j, void *buf)
|
||||
static int count_tags(journal_t *journal, struct buffer_head *bh)
|
||||
{
|
||||
char * tagp;
|
||||
journal_block_tag_t * tag;
|
||||
journal_block_tag_t tag;
|
||||
int nr = 0, size = journal->j_blocksize;
|
||||
int tag_bytes = journal_tag_bytes(journal);
|
||||
|
||||
@ -206,14 +206,14 @@ static int count_tags(journal_t *journal, struct buffer_head *bh)
|
||||
tagp = &bh->b_data[sizeof(journal_header_t)];
|
||||
|
||||
while ((tagp - bh->b_data + tag_bytes) <= size) {
|
||||
tag = (journal_block_tag_t *) tagp;
|
||||
memcpy(&tag, tagp, sizeof(tag));
|
||||
|
||||
nr++;
|
||||
tagp += tag_bytes;
|
||||
if (!(tag->t_flags & cpu_to_be16(JBD2_FLAG_SAME_UUID)))
|
||||
if (!(tag.t_flags & cpu_to_be16(JBD2_FLAG_SAME_UUID)))
|
||||
tagp += 16;
|
||||
|
||||
if (tag->t_flags & cpu_to_be16(JBD2_FLAG_LAST_TAG))
|
||||
if (tag.t_flags & cpu_to_be16(JBD2_FLAG_LAST_TAG))
|
||||
break;
|
||||
}
|
||||
|
||||
@ -433,9 +433,9 @@ static int jbd2_commit_block_csum_verify(journal_t *j, void *buf)
|
||||
}
|
||||
|
||||
static int jbd2_block_tag_csum_verify(journal_t *j, journal_block_tag_t *tag,
|
||||
journal_block_tag3_t *tag3,
|
||||
void *buf, __u32 sequence)
|
||||
{
|
||||
journal_block_tag3_t *tag3 = (journal_block_tag3_t *)tag;
|
||||
__u32 csum32;
|
||||
__be32 seq;
|
||||
|
||||
@ -496,7 +496,7 @@ static int do_one_pass(journal_t *journal,
|
||||
while (1) {
|
||||
int flags;
|
||||
char * tagp;
|
||||
journal_block_tag_t * tag;
|
||||
journal_block_tag_t tag;
|
||||
struct buffer_head * obh;
|
||||
struct buffer_head * nbh;
|
||||
|
||||
@ -613,8 +613,8 @@ static int do_one_pass(journal_t *journal,
|
||||
<= journal->j_blocksize - descr_csum_size) {
|
||||
unsigned long io_block;
|
||||
|
||||
tag = (journal_block_tag_t *) tagp;
|
||||
flags = be16_to_cpu(tag->t_flags);
|
||||
memcpy(&tag, tagp, sizeof(tag));
|
||||
flags = be16_to_cpu(tag.t_flags);
|
||||
|
||||
io_block = next_log_block++;
|
||||
wrap(journal, next_log_block);
|
||||
@ -632,7 +632,7 @@ static int do_one_pass(journal_t *journal,
|
||||
|
||||
J_ASSERT(obh != NULL);
|
||||
blocknr = read_tag_block(journal,
|
||||
tag);
|
||||
&tag);
|
||||
|
||||
/* If the block has been
|
||||
* revoked, then we're all done
|
||||
@ -647,8 +647,8 @@ static int do_one_pass(journal_t *journal,
|
||||
|
||||
/* Look for block corruption */
|
||||
if (!jbd2_block_tag_csum_verify(
|
||||
journal, tag, obh->b_data,
|
||||
be32_to_cpu(tmp->h_sequence))) {
|
||||
journal, &tag, (journal_block_tag3_t *)tagp,
|
||||
obh->b_data, be32_to_cpu(tmp->h_sequence))) {
|
||||
brelse(obh);
|
||||
success = -EFSBADCRC;
|
||||
printk(KERN_ERR "JBD2: Invalid "
|
||||
|
Loading…
Reference in New Issue
Block a user