changeset 1257:9c372d07da55

objstore: add cleanup txn entry function that runs always Regardless of if the transaction commited or aborted, this callback is always executed. It is intended for lock release, temporary memory freeing, etc. Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
date Sat, 17 Dec 2022 14:30:03 -0500
parents dc84208232c6
children 6fa5635525c9
files src/objstore/include/nomad/objstore_backend.h src/objstore/txn.c
diffstat 2 files changed, 20 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/objstore/include/nomad/objstore_backend.h	Sat Dec 17 14:26:39 2022 -0500
+++ b/src/objstore/include/nomad/objstore_backend.h	Sat Dec 17 14:30:03 2022 -0500
@@ -137,6 +137,7 @@
 
 	int (*perform)(struct txn *txn, struct txn_entry *entry);
 	void (*rollback)(struct txn *txn, struct txn_entry *entry);
+	void (*cleanup)(struct txn *txn, struct txn_entry *entry);
 
 	union {
 		struct {
--- a/src/objstore/txn.c	Sat Dec 17 14:26:39 2022 -0500
+++ b/src/objstore/txn.c	Sat Dec 17 14:30:03 2022 -0500
@@ -121,6 +121,7 @@
 		txn->entries[i].failed = false;
 		txn->entries[i].perform = NULL;
 		txn->entries[i].rollback = NULL;
+		txn->entries[i].cleanup = NULL;
 	}
 
 	return clone->ops->txn_begin(txn);
@@ -150,6 +151,24 @@
 		}
 	}
 
+	/* must iterate backwards to avoid use-after-free */
+	for (i = ARRAY_LEN(txn->entries); i >= 0; i--) {
+		struct txn_entry *entry = &txn->entries[i];
+
+		switch (entry->op) {
+			case OP_NOP:
+				/* nothing to do */
+				break;
+			case OP_COW:
+			case OP_CREATE:
+			case OP_SETATTR:
+			case OP_WRITE:
+				if (entry->cleanup)
+					entry->cleanup(txn, entry);
+				break;
+		}
+	}
+
 	memset(txn, 0x7c, sizeof(struct txn));
 }