shithub: lwext4

Download patch

ref: 29b69c630d36e29b9e683f3a2fc96edc60cc579b
parent: 21375b10667c088455dc123350c977a73cd1bd6b
author: ngkaho1234 <ngkaho1234@gmail.com>
date: Fri Dec 25 20:16:44 EST 2015

ext4_journal: keep track of blocks added to a transaction.

--- a/lwext4/ext4_journal.c
+++ b/lwext4/ext4_journal.c
@@ -101,8 +101,20 @@
 	return 0;
 }
 
+static int
+jbd_block_rec_cmp(struct jbd_block_rec *a, struct jbd_block_rec *b)
+{
+	if (a->lba > b->lba)
+		return 1;
+	else if (a->lba < b->lba)
+		return -1;
+	return 0;
+}
+
 RB_GENERATE_INTERNAL(jbd_revoke, revoke_entry, revoke_node,
 		     jbd_revoke_entry_cmp, static inline)
+RB_GENERATE_INTERNAL(jbd_block, jbd_block_rec, block_rec_node,
+		     jbd_block_rec_cmp, static inline)
 
 #define jbd_alloc_revoke_entry() calloc(1, sizeof(struct revoke_entry))
 #define jbd_free_revoke_entry(addr) free(addr)
@@ -1080,6 +1092,8 @@
 	if (!trans)
 		return NULL;
 
+	RB_INIT(&trans->block_rec_root);
+
 	/* We will assign a trans_id to this transaction,
 	 * once it has been committed.*/
 	trans->journal = journal;
@@ -1114,6 +1128,46 @@
 	return r;
 }
 
+static inline int
+jbd_trans_insert_block_rec(struct jbd_trans *trans,
+			   ext4_fsblk_t lba)
+{
+	struct jbd_block_rec *block_rec;
+	block_rec = calloc(1, sizeof(struct jbd_block_rec));
+	if (!block_rec)
+		return ENOMEM;
+
+	block_rec->lba = lba;
+	RB_INSERT(jbd_block, &trans->block_rec_root, block_rec);
+	return EOK;
+}
+
+static struct jbd_block_rec *
+jbd_trans_block_rec_lookup(struct jbd_trans *trans,
+			   ext4_fsblk_t lba)
+{
+	struct jbd_block_rec tmp = {
+		.lba = lba
+	};
+
+	return RB_FIND(jbd_block, &trans->block_rec_root, &tmp);
+}
+
+static inline void
+jbd_trans_remove_block_recs(struct jbd_trans *trans)
+{
+	struct jbd_block_rec *block_rec, *tmp;
+	RB_FOREACH_SAFE(block_rec,
+			jbd_block,
+			&trans->block_rec_root,
+			tmp) {
+		RB_REMOVE(jbd_block,
+			  &trans->block_rec_root,
+			  block_rec);
+		free(block_rec);
+	}
+}
+
 /**@brief  Add block to a transaction and mark it dirty.
  * @param  trans transaction
  * @param  block block descriptor
@@ -1129,6 +1183,11 @@
 		if (!buf)
 			return ENOMEM;
 
+		if (jbd_trans_insert_block_rec(trans, block->lb_id) != EOK) {
+			free(buf);
+			return ENOMEM;
+		}
+
 		buf->trans = trans;
 		buf->block = *block;
 		ext4_bcache_inc_ref(block->buf);
@@ -1193,6 +1252,7 @@
 		free(rec);
 	}
 
+	jbd_trans_remove_block_recs(trans);
 	free(trans);
 }
 
--- a/lwext4/ext4_types.h
+++ b/lwext4/ext4_types.h
@@ -1104,6 +1104,11 @@
 	LIST_ENTRY(jbd_revoke_rec) revoke_node;
 };
 
+struct jbd_block_rec {
+	ext4_fsblk_t lba;
+	RB_ENTRY(jbd_block_rec) block_rec_node;
+};
+
 struct jbd_trans {
 	uint32_t trans_id;
 
@@ -1117,6 +1122,7 @@
 
 	LIST_HEAD(jbd_trans_buf, jbd_buf) buf_list;
 	LIST_HEAD(jbd_revoke_list, jbd_revoke_rec) revoke_list;
+	RB_HEAD(jbd_block, jbd_block_rec) block_rec_root;
 	TAILQ_ENTRY(jbd_trans) trans_node;
 };