aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jbd2/commit.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/jbd2/commit.c')
-rw-r--r--fs/jbd2/commit.c70
1 files changed, 67 insertions, 3 deletions
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
index 840f70f50792..216f4299f65e 100644
--- a/fs/jbd2/commit.c
+++ b/fs/jbd2/commit.c
@@ -85,6 +85,24 @@ nope:
85 __brelse(bh); 85 __brelse(bh);
86} 86}
87 87
88static void jbd2_commit_block_csum_set(journal_t *j,
89 struct journal_head *descriptor)
90{
91 struct commit_header *h;
92 __u32 csum;
93
94 if (!JBD2_HAS_INCOMPAT_FEATURE(j, JBD2_FEATURE_INCOMPAT_CSUM_V2))
95 return;
96
97 h = (struct commit_header *)(jh2bh(descriptor)->b_data);
98 h->h_chksum_type = 0;
99 h->h_chksum_size = 0;
100 h->h_chksum[0] = 0;
101 csum = jbd2_chksum(j, j->j_csum_seed, jh2bh(descriptor)->b_data,
102 j->j_blocksize);
103 h->h_chksum[0] = cpu_to_be32(csum);
104}
105
88/* 106/*
89 * Done it all: now submit the commit record. We should have 107 * Done it all: now submit the commit record. We should have
90 * cleaned up our previous buffers by now, so if we are in abort 108 * cleaned up our previous buffers by now, so if we are in abort
@@ -128,6 +146,7 @@ static int journal_submit_commit_record(journal_t *journal,
128 tmp->h_chksum_size = JBD2_CRC32_CHKSUM_SIZE; 146 tmp->h_chksum_size = JBD2_CRC32_CHKSUM_SIZE;
129 tmp->h_chksum[0] = cpu_to_be32(crc32_sum); 147 tmp->h_chksum[0] = cpu_to_be32(crc32_sum);
130 } 148 }
149 jbd2_commit_block_csum_set(journal, descriptor);
131 150
132 JBUFFER_TRACE(descriptor, "submit commit block"); 151 JBUFFER_TRACE(descriptor, "submit commit block");
133 lock_buffer(bh); 152 lock_buffer(bh);
@@ -301,6 +320,44 @@ static void write_tag_block(int tag_bytes, journal_block_tag_t *tag,
301 tag->t_blocknr_high = cpu_to_be32((block >> 31) >> 1); 320 tag->t_blocknr_high = cpu_to_be32((block >> 31) >> 1);
302} 321}
303 322
323static void jbd2_descr_block_csum_set(journal_t *j,
324 struct journal_head *descriptor)
325{
326 struct jbd2_journal_block_tail *tail;
327 __u32 csum;
328
329 if (!JBD2_HAS_INCOMPAT_FEATURE(j, JBD2_FEATURE_INCOMPAT_CSUM_V2))
330 return;
331
332 tail = (struct jbd2_journal_block_tail *)
333 (jh2bh(descriptor)->b_data + j->j_blocksize -
334 sizeof(struct jbd2_journal_block_tail));
335 tail->t_checksum = 0;
336 csum = jbd2_chksum(j, j->j_csum_seed, jh2bh(descriptor)->b_data,
337 j->j_blocksize);
338 tail->t_checksum = cpu_to_be32(csum);
339}
340
341static void jbd2_block_tag_csum_set(journal_t *j, journal_block_tag_t *tag,
342 struct buffer_head *bh, __u32 sequence)
343{
344 struct page *page = bh->b_page;
345 __u8 *addr;
346 __u32 csum;
347
348 if (!JBD2_HAS_INCOMPAT_FEATURE(j, JBD2_FEATURE_INCOMPAT_CSUM_V2))
349 return;
350
351 sequence = cpu_to_be32(sequence);
352 addr = kmap_atomic(page, KM_USER0);
353 csum = jbd2_chksum(j, j->j_csum_seed, (__u8 *)&sequence,
354 sizeof(sequence));
355 csum = jbd2_chksum(j, csum, addr + offset_in_page(bh->b_data),
356 bh->b_size);
357 kunmap_atomic(addr, KM_USER0);
358
359 tag->t_checksum = cpu_to_be32(csum);
360}
304/* 361/*
305 * jbd2_journal_commit_transaction 362 * jbd2_journal_commit_transaction
306 * 363 *
@@ -334,6 +391,10 @@ void jbd2_journal_commit_transaction(journal_t *journal)
334 unsigned long first_block; 391 unsigned long first_block;
335 tid_t first_tid; 392 tid_t first_tid;
336 int update_tail; 393 int update_tail;
394 int csum_size = 0;
395
396 if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_CSUM_V2))
397 csum_size = sizeof(struct jbd2_journal_block_tail);
337 398
338 /* 399 /*
339 * First job: lock down the current transaction and wait for 400 * First job: lock down the current transaction and wait for
@@ -627,7 +688,9 @@ void jbd2_journal_commit_transaction(journal_t *journal)
627 688
628 tag = (journal_block_tag_t *) tagp; 689 tag = (journal_block_tag_t *) tagp;
629 write_tag_block(tag_bytes, tag, jh2bh(jh)->b_blocknr); 690 write_tag_block(tag_bytes, tag, jh2bh(jh)->b_blocknr);
630 tag->t_flags = cpu_to_be32(tag_flag); 691 tag->t_flags = cpu_to_be16(tag_flag);
692 jbd2_block_tag_csum_set(journal, tag, jh2bh(new_jh),
693 commit_transaction->t_tid);
631 tagp += tag_bytes; 694 tagp += tag_bytes;
632 space_left -= tag_bytes; 695 space_left -= tag_bytes;
633 696
@@ -643,7 +706,7 @@ void jbd2_journal_commit_transaction(journal_t *journal)
643 706
644 if (bufs == journal->j_wbufsize || 707 if (bufs == journal->j_wbufsize ||
645 commit_transaction->t_buffers == NULL || 708 commit_transaction->t_buffers == NULL ||
646 space_left < tag_bytes + 16) { 709 space_left < tag_bytes + 16 + csum_size) {
647 710
648 jbd_debug(4, "JBD2: Submit %d IOs\n", bufs); 711 jbd_debug(4, "JBD2: Submit %d IOs\n", bufs);
649 712
@@ -651,8 +714,9 @@ void jbd2_journal_commit_transaction(journal_t *journal)
651 submitting the IOs. "tag" still points to 714 submitting the IOs. "tag" still points to
652 the last tag we set up. */ 715 the last tag we set up. */
653 716
654 tag->t_flags |= cpu_to_be32(JBD2_FLAG_LAST_TAG); 717 tag->t_flags |= cpu_to_be16(JBD2_FLAG_LAST_TAG);
655 718
719 jbd2_descr_block_csum_set(journal, descriptor);
656start_journal_io: 720start_journal_io:
657 for (i = 0; i < bufs; i++) { 721 for (i = 0; i < bufs; i++) {
658 struct buffer_head *bh = wbuf[i]; 722 struct buffer_head *bh = wbuf[i];