Skip to content

Commit

Permalink
jbd2: unify revoke and tag block checksum handling
Browse files Browse the repository at this point in the history
Revoke and tag descriptor blocks are just different kinds of descriptor
blocks and thus have checksum in the same place. Unify computation and
checking of checksums for these.

Reviewed-by: Darrick J. Wong <[email protected]>
Signed-off-by: Jan Kara <[email protected]>
Signed-off-by: Theodore Ts'o <[email protected]>
  • Loading branch information
jankara authored and tytso committed Feb 23, 2016
1 parent 32ab671 commit 1101cd4
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 66 deletions.
18 changes: 1 addition & 17 deletions fs/jbd2/commit.c
Original file line number Diff line number Diff line change
Expand Up @@ -317,22 +317,6 @@ static void write_tag_block(journal_t *j, journal_block_tag_t *tag,
tag->t_blocknr_high = cpu_to_be32((block >> 31) >> 1);
}

static void jbd2_descr_block_csum_set(journal_t *j,
struct buffer_head *bh)
{
struct jbd2_journal_block_tail *tail;
__u32 csum;

if (!jbd2_journal_has_csum_v2or3(j))
return;

tail = (struct jbd2_journal_block_tail *)(bh->b_data + j->j_blocksize -
sizeof(struct jbd2_journal_block_tail));
tail->t_checksum = 0;
csum = jbd2_chksum(j, j->j_csum_seed, bh->b_data, j->j_blocksize);
tail->t_checksum = cpu_to_be32(csum);
}

static void jbd2_block_tag_csum_set(journal_t *j, journal_block_tag_t *tag,
struct buffer_head *bh, __u32 sequence)
{
Expand Down Expand Up @@ -714,7 +698,7 @@ void jbd2_journal_commit_transaction(journal_t *journal)

tag->t_flags |= cpu_to_be16(JBD2_FLAG_LAST_TAG);

jbd2_descr_block_csum_set(journal, descriptor);
jbd2_descriptor_block_csum_set(journal, descriptor);
start_journal_io:
for (i = 0; i < bufs; i++) {
struct buffer_head *bh = wbuf[i];
Expand Down
15 changes: 15 additions & 0 deletions fs/jbd2/journal.c
Original file line number Diff line number Diff line change
Expand Up @@ -834,6 +834,21 @@ jbd2_journal_get_descriptor_buffer(transaction_t *transaction, int type)
return bh;
}

void jbd2_descriptor_block_csum_set(journal_t *j, struct buffer_head *bh)
{
struct jbd2_journal_block_tail *tail;
__u32 csum;

if (!jbd2_journal_has_csum_v2or3(j))
return;

tail = (struct jbd2_journal_block_tail *)(bh->b_data + j->j_blocksize -
sizeof(struct jbd2_journal_block_tail));
tail->t_checksum = 0;
csum = jbd2_chksum(j, j->j_csum_seed, bh->b_data, j->j_blocksize);
tail->t_checksum = cpu_to_be32(csum);
}

/*
* Return tid of the oldest transaction in the journal and block in the journal
* where the transaction starts.
Expand Down
31 changes: 5 additions & 26 deletions fs/jbd2/recovery.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,7 @@ static int jread(struct buffer_head **bhp, journal_t *journal,
return 0;
}

static int jbd2_descr_block_csum_verify(journal_t *j,
void *buf)
static int jbd2_descriptor_block_csum_verify(journal_t *j, void *buf)
{
struct jbd2_journal_block_tail *tail;
__be32 provided;
Expand Down Expand Up @@ -522,8 +521,8 @@ static int do_one_pass(journal_t *journal,
descr_csum_size =
sizeof(struct jbd2_journal_block_tail);
if (descr_csum_size > 0 &&
!jbd2_descr_block_csum_verify(journal,
bh->b_data)) {
!jbd2_descriptor_block_csum_verify(journal,
bh->b_data)) {
printk(KERN_ERR "JBD2: Invalid checksum "
"recovering block %lu in log\n",
next_log_block);
Expand Down Expand Up @@ -811,26 +810,6 @@ static int do_one_pass(journal_t *journal,
return err;
}

static int jbd2_revoke_block_csum_verify(journal_t *j,
void *buf)
{
struct jbd2_journal_revoke_tail *tail;
__be32 provided;
__u32 calculated;

if (!jbd2_journal_has_csum_v2or3(j))
return 1;

tail = (struct jbd2_journal_revoke_tail *)(buf + j->j_blocksize -
sizeof(struct jbd2_journal_revoke_tail));
provided = tail->r_checksum;
tail->r_checksum = 0;
calculated = jbd2_chksum(j, j->j_csum_seed, buf, j->j_blocksize);
tail->r_checksum = provided;

return provided == cpu_to_be32(calculated);
}

/* Scan a revoke record, marking all blocks mentioned as revoked. */

static int scan_revoke_records(journal_t *journal, struct buffer_head *bh,
Expand All @@ -846,11 +825,11 @@ static int scan_revoke_records(journal_t *journal, struct buffer_head *bh,
offset = sizeof(jbd2_journal_revoke_header_t);
rcount = be32_to_cpu(header->r_count);

if (!jbd2_revoke_block_csum_verify(journal, header))
if (!jbd2_descriptor_block_csum_verify(journal, header))
return -EFSBADCRC;

if (jbd2_journal_has_csum_v2or3(journal))
csum_size = sizeof(struct jbd2_journal_revoke_tail);
csum_size = sizeof(struct jbd2_journal_block_tail);
if (rcount > journal->j_blocksize - csum_size)
return -EINVAL;
max = rcount;
Expand Down
19 changes: 2 additions & 17 deletions fs/jbd2/revoke.c
Original file line number Diff line number Diff line change
Expand Up @@ -583,7 +583,7 @@ static void write_one_revoke_record(transaction_t *transaction,

/* Do we need to leave space at the end for a checksum? */
if (jbd2_journal_has_csum_v2or3(journal))
csum_size = sizeof(struct jbd2_journal_revoke_tail);
csum_size = sizeof(struct jbd2_journal_block_tail);

if (jbd2_has_feature_64bit(journal))
sz = 8;
Expand Down Expand Up @@ -623,21 +623,6 @@ static void write_one_revoke_record(transaction_t *transaction,
*offsetp = offset;
}

static void jbd2_revoke_csum_set(journal_t *j, struct buffer_head *bh)
{
struct jbd2_journal_revoke_tail *tail;
__u32 csum;

if (!jbd2_journal_has_csum_v2or3(j))
return;

tail = (struct jbd2_journal_revoke_tail *)(bh->b_data + j->j_blocksize -
sizeof(struct jbd2_journal_revoke_tail));
tail->r_checksum = 0;
csum = jbd2_chksum(j, j->j_csum_seed, bh->b_data, j->j_blocksize);
tail->r_checksum = cpu_to_be32(csum);
}

/*
* Flush a revoke descriptor out to the journal. If we are aborting,
* this is a noop; otherwise we are generating a buffer which needs to
Expand All @@ -658,7 +643,7 @@ static void flush_descriptor(journal_t *journal,

header = (jbd2_journal_revoke_header_t *)descriptor->b_data;
header->r_count = cpu_to_be32(offset);
jbd2_revoke_csum_set(journal, descriptor);
jbd2_descriptor_block_csum_set(journal, descriptor);

set_buffer_jwrite(descriptor);
BUFFER_TRACE(descriptor, "write");
Expand Down
8 changes: 2 additions & 6 deletions include/linux/jbd2.h
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ typedef struct journal_block_tag_s
__be32 t_blocknr_high; /* most-significant high 32bits. */
} journal_block_tag_t;

/* Tail of descriptor block, for checksumming */
/* Tail of descriptor or revoke block, for checksumming */
struct jbd2_journal_block_tail {
__be32 t_checksum; /* crc32c(uuid+descr_block) */
};
Expand All @@ -215,11 +215,6 @@ typedef struct jbd2_journal_revoke_header_s
__be32 r_count; /* Count of bytes used in the block */
} jbd2_journal_revoke_header_t;

/* Tail of revoke block, for checksumming */
struct jbd2_journal_revoke_tail {
__be32 r_checksum; /* crc32c(uuid+revoke_block) */
};

/* Definitions for the journal tag flags word: */
#define JBD2_FLAG_ESCAPE 1 /* on-disk block is escaped */
#define JBD2_FLAG_SAME_UUID 2 /* block has same uuid as previous */
Expand Down Expand Up @@ -1138,6 +1133,7 @@ static inline void jbd2_unfile_log_bh(struct buffer_head *bh)

/* Log buffer allocation */
struct buffer_head *jbd2_journal_get_descriptor_buffer(transaction_t *, int);
void jbd2_descriptor_block_csum_set(journal_t *, struct buffer_head *);
int jbd2_journal_next_log_block(journal_t *, unsigned long long *);
int jbd2_journal_get_log_tail(journal_t *journal, tid_t *tid,
unsigned long *block);
Expand Down

0 comments on commit 1101cd4

Please sign in to comment.