Mercurial > nomad > experimental
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)); }