ref: 49da2ec21021231241d88b1ffc73fd243dd3e77c
parent: 07ef5d4916b1b81d98825529665fd6d6dc177c4d
author: ngkaho1234 <[email protected]>
date: Mon Dec 14 09:39:41 EST 2015
ext4_journal: fixes on numorous bugs, see below. - UUID not being copied to tail of a block tag when needed. - checkpoint queue not initialized. - ext4_block_set on non-existing journal bdev. - journal superblock not flushed to disk immediately.
--- a/lwext4/ext4_journal.c
+++ b/lwext4/ext4_journal.c
@@ -359,7 +359,7 @@
JBD_FEATURE_INCOMPAT_64BIT))
jbd_set32(tag, blocknr_high, tag_info->block >> 32);
- if (!tag_info->uuid_exist) {
+ if (tag_info->uuid_exist) {
if (remain_buf_size - tag_bytes < UUID_SIZE)
return EINVAL;
@@ -366,9 +366,9 @@
uuid_start = (char *)tag + tag_bytes;
tag_info->tag_bytes += UUID_SIZE;
memcpy(uuid_start, tag_info->uuid, UUID_SIZE);
+ } else
jbd_set32(tag, flags,
jbd_get32(tag, flags) | JBD_FLAG_SAME_UUID);
- }
if (tag_info->last_tag)
jbd_set32(tag, flags,
@@ -381,7 +381,7 @@
JBD_FEATURE_INCOMPAT_64BIT))
jbd_set32(tag, blocknr_high, tag_info->block >> 32);
- if (!tag_info->uuid_exist) {
+ if (tag_info->uuid_exist) {
if (remain_buf_size - tag_bytes < UUID_SIZE)
return EINVAL;
@@ -388,9 +388,9 @@
uuid_start = (char *)tag + tag_bytes;
tag_info->tag_bytes += UUID_SIZE;
memcpy(uuid_start, tag_info->uuid, UUID_SIZE);
+ } else
jbd_set16(tag, flags,
jbd_get16(tag, flags) | JBD_FLAG_SAME_UUID);
- }
if (tag_info->last_tag)
jbd_set16(tag, flags,
@@ -786,6 +786,7 @@
journal->block_size = jbd_get32(&jbd_fs->sb, blocksize);
TAILQ_INIT(&journal->trans_queue);
+ TAILQ_INIT(&journal->cp_queue);
journal->jbd_fs = jbd_fs;
jbd_journal_write_sb(journal);
return jbd_write_sb(jbd_fs);
@@ -865,10 +866,11 @@
{
struct jbd_buf *jbd_buf, *tmp;
struct jbd_revoke_rec *rec, *tmp2;
+ struct ext4_fs *fs = journal->jbd_fs->inode_ref.fs;
LIST_FOREACH_SAFE(jbd_buf, &trans->buf_list, buf_node,
tmp) {
if (abort)
- ext4_block_set(journal->jbd_fs->bdev, &jbd_buf->block);
+ ext4_block_set(fs->bdev, &jbd_buf->block);
LIST_REMOVE(jbd_buf, buf_node);
free(jbd_buf);
@@ -897,9 +899,9 @@
return rc;
header = (struct jbd_commit_header *)commit_block.data;
- header->header.magic = JBD_MAGIC_NUMBER;
- header->header.blocktype = JBD_COMMIT_BLOCK;
- header->header.sequence = trans->trans_id;
+ jbd_set32(&header->header, magic, JBD_MAGIC_NUMBER);
+ jbd_set32(&header->header, blocktype, JBD_COMMIT_BLOCK);
+ jbd_set32(&header->header, sequence, trans->trans_id);
ext4_bcache_set_dirty(commit_block.buf);
rc = jbd_block_set(journal->jbd_fs, &commit_block);
@@ -929,15 +931,15 @@
desc_iblock = jbd_journal_alloc_block(journal, trans);
rc = jbd_block_get_noread(journal->jbd_fs,
&desc_block, desc_iblock);
- if (!rc)
+ if (rc != EOK)
break;
ext4_bcache_set_dirty(desc_block.buf);
bhdr = (struct jbd_bhdr *)desc_block.data;
- bhdr->magic = JBD_MAGIC_NUMBER;
- bhdr->blocktype = JBD_DESCRIPTOR_BLOCK;
- bhdr->sequence = trans->trans_id;
+ jbd_set32(bhdr, magic, JBD_MAGIC_NUMBER);
+ jbd_set32(bhdr, blocktype, JBD_DESCRIPTOR_BLOCK);
+ jbd_set32(bhdr, sequence, trans->trans_id);
tag_start = (char *)(bhdr + 1);
tag_ptr = tag_start;
@@ -1015,7 +1017,7 @@
desc_iblock = jbd_journal_alloc_block(journal, trans);
rc = jbd_block_get_noread(journal->jbd_fs,
&desc_block, desc_iblock);
- if (!rc) {
+ if (rc != EOK) {
break;
}
@@ -1022,9 +1024,9 @@
ext4_bcache_set_dirty(desc_block.buf);
bhdr = (struct jbd_bhdr *)desc_block.data;
- bhdr->magic = JBD_MAGIC_NUMBER;
- bhdr->blocktype = JBD_REVOKE_BLOCK;
- bhdr->sequence = trans->trans_id;
+ jbd_set32(bhdr, magic, JBD_MAGIC_NUMBER);
+ jbd_set32(bhdr, blocktype, JBD_REVOKE_BLOCK);
+ jbd_set32(bhdr, sequence, trans->trans_id);
header = (struct jbd_revoke_header *)bhdr;
blocks_entry = (char *)(header + 1);
@@ -1075,9 +1077,10 @@
void jbd_journal_cp_trans(struct jbd_journal *journal, struct jbd_trans *trans)
{
struct jbd_buf *jbd_buf, *tmp;
+ struct ext4_fs *fs = journal->jbd_fs->inode_ref.fs;
LIST_FOREACH_SAFE(jbd_buf, &trans->buf_list, buf_node,
tmp) {
- ext4_block_set(journal->jbd_fs->bdev, &jbd_buf->block);
+ ext4_block_set(fs->bdev, &jbd_buf->block);
}
}
@@ -1097,6 +1100,7 @@
journal->start += trans->alloc_blocks;
journal->trans_id = ++trans->trans_id;
jbd_journal_write_sb(journal);
+ jbd_write_sb(journal->jbd_fs);
jbd_journal_free_trans(journal, trans, false);
if ((trans = TAILQ_FIRST(&journal->cp_queue))) {