shithub: lwext4

Download patch

ref: 093f60969f083427b5354ba3344297b6194ed106
parent: 4b25da872742a15a49343f758e16d5e0447d1c48
author: ngkaho1234 <[email protected]>
date: Tue Dec 8 10:58:33 EST 2015

ext4_journal: journal write skeleton code part 2.

--- a/lwext4/ext4_journal.c
+++ b/lwext4/ext4_journal.c
@@ -887,8 +887,6 @@
 	struct jbd_buf *jbd_buf;
 	struct ext4_block desc_block, data_block;
 
-	tag_tbl_size = journal->block_size - sizeof(struct jbd_bhdr);
-
 	LIST_FOREACH(jbd_buf, &trans->buf_list, buf_node) {
 		struct tag_info tag_info;
 		bool uuid_exist = false;
@@ -907,9 +905,12 @@
 			bhdr->magic = JBD_MAGIC_NUMBER;
 			bhdr->blocktype = JBD_DESCRIPTOR_BLOCK;
 			bhdr->sequence = trans->trans_id;
+
 			tag_start = (char *)(bhdr + 1);
 			tag_ptr = tag_start;
 			uuid_exist = true;
+			tag_tbl_size = journal->block_size -
+				sizeof(struct jbd_bhdr);
 		}
 		tag_info.block = jbd_buf->block.lb_id;
 		tag_info.uuid_exist = uuid_exist;
@@ -955,6 +956,80 @@
 
 	if (desc_iblock)
 		jbd_block_set(journal->jbd_fs, &desc_block);
+
+	return rc;
+}
+
+static int
+jbd_journal_prepare_revoke(struct jbd_journal *journal,
+			   struct jbd_trans *trans)
+{
+	int rc = EOK, i = 0;
+	int32_t tag_tbl_size;
+	uint32_t desc_iblock = 0;
+	char *blocks_entry = NULL;
+	struct jbd_revoke_rec *rec;
+	struct ext4_block desc_block;
+	struct jbd_revoke_header *header = NULL;
+	int32_t record_len = 4;
+
+	if (JBD_HAS_INCOMPAT_FEATURE(&journal->jbd_fs->sb,
+				     JBD_FEATURE_INCOMPAT_64BIT))
+		record_len = 8;
+
+	LIST_FOREACH(rec, &trans->revoke_list, revoke_node) {
+again:
+		if (!desc_iblock) {
+			struct jbd_bhdr *bhdr;
+			desc_iblock = jbd_journal_alloc_block(journal);
+			rc = jbd_block_get_noread(journal->jbd_fs,
+					   &desc_block, desc_iblock);
+			if (!rc)
+				break;
+
+			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;
+			
+			header = (struct jbd_revoke_header *)bhdr;
+			blocks_entry = (char *)(header + 1);
+			tag_tbl_size = journal->block_size -
+				sizeof(struct jbd_bhdr);
+		}
+
+		if (tag_tbl_size < record_len) {
+			header->count = journal->block_size - tag_tbl_size;
+			jbd_block_set(journal->jbd_fs, &desc_block);
+			desc_iblock = 0;
+			header = NULL;
+			goto again;
+		}
+		if (record_len == 8) {
+			uint64_t *blocks =
+				(uint64_t *)blocks_entry;
+			*blocks = to_be64(rec->lba);
+		} else {
+			uint32_t *blocks =
+				(uint32_t *)blocks_entry;
+			*blocks = to_be32(rec->lba);
+		}
+		blocks_entry += record_len;
+		tag_tbl_size -= record_len;
+
+		i++;
+	}
+	if (rc != EOK)
+		jbd_journal_abort_trans(journal, trans);
+
+	if (desc_iblock) {
+		if (header != NULL)
+			header->count = journal->block_size - tag_tbl_size;
+
+		jbd_block_set(journal->jbd_fs, &desc_block);
+	}
 
 	return rc;
 }