[RFC][Update][Patch 9/16]Fix reading of 32-bit tag descriptors

Mingming Cao
2006-06-30T00:19:00Z

We must never attempt to read the high 32-bits of a descriptor tag on
a 32-bit journal, even when CONFIG_LBD is set, as we'll end up reading
garbage from the subsequent tag.

Signed-off-by: Stephen Tweedie <sct@redhat.com>
Acked-by: Badari Pulavarty <pbadari@us.ibm.com>

---

linux-2.6.17-ming/fs/jbd/recovery.c | 13 +++++++------
1 files changed, 7 insertions(+), 6 deletions(-)

diff -puN fs/jbd/recovery.c~jbd-read-32bit-tag-fix fs/jbd/recovery.c
--- linux-2.6.17/fs/jbd/recovery.c~jbd-read-32bit-tag-fix 2006-06-28 16:47:02.555278191 -0700
+++ linux-2.6.17-ming/fs/jbd/recovery.c 2006-06-28 16:47:02.558277847 -0700
@@ -308,11 +308,12 @@ int journal_skip_recovery(journal_t *jou
return err;
}

-static inline u64 read_split_be64(__be32 *high, __be32 *low)
+static inline sector_t read_tag_block(int tag_bytes, journal_block_tag_t *tag)
{
- u64 ret = be32_to_cpu(*low);
- ret |= (u64)be32_to_cpu(*high) << 32;
- return ret;
+ sector_t block = be32_to_cpu(tag->t_blocknr);
+ if (tag_bytes > JBD_TAG_SIZE32)
+ block |= (u64)be32_to_cpu(tag->t_blocknr_high) << 32;
+ return block;
}

static int do_one_pass(journal_t *journal,
@@ -454,8 +455,8 @@ static int do_one_pass(journal_t *journa
unsigned long blocknr;

J_ASSERT(obh != NULL);
- blocknr = read_split_be64(&tag->t_blocknr_high,
- &tag->t_blocknr);
+ blocknr = read_tag_block(tag_bytes,
+ tag);

/* If the block has been
* revoked, then we're all done

_