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;
};