Mercurial > nomad
changeset 843:5427f4e9dcb6
objstore: implement a attach/detach objver to txn helpers
This rewrites the previous logic that tried to keep track of minimum
truncation size.
Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author | Josef 'Jeff' Sipek <jeffpc@josefsipek.net> |
---|---|
date | Fri, 16 Dec 2022 19:46:24 -0500 |
parents | b0852eac72a9 |
children | 77fd01b82fd7 |
files | src/objstore/include/nomad/objstore_backend.h src/objstore/obj.c src/objstore/obj_txn.c src/objstore/objstore_impl.h |
diffstat | 4 files changed, 74 insertions(+), 31 deletions(-) [+] |
line wrap: on
line diff
--- a/src/objstore/include/nomad/objstore_backend.h Thu Dec 15 23:22:15 2022 -0500 +++ b/src/objstore/include/nomad/objstore_backend.h Fri Dec 16 19:46:24 2022 -0500 @@ -91,11 +91,12 @@ */ struct objstore_open_obj_info *open[2]; + /* transaction related state */ struct { - uint64_t cookie; - - /* setattr */ - uint64_t min_size; /* the shorted truncation */ + struct txn *txn; /* active txn */ + int refcnt; /* number of attaches */ + struct objver *prev_ver; /* version we cow'd from */ + uint64_t min_data_size; /* the shortest truncation so far */ } txn; /* misc */
--- a/src/objstore/obj.c Thu Dec 15 23:22:15 2022 -0500 +++ b/src/objstore/obj.c Fri Dec 16 19:46:24 2022 -0500 @@ -112,8 +112,10 @@ ver->private = NULL; for (i = 0; i < ARRAY_LEN(ver->open); i++) ver->open[i] = NULL; - ver->txn.cookie = UINT64_MAX; - ver->txn.min_size = 0; + ver->txn.txn = NULL; + ver->txn.refcnt = 0; + ver->txn.prev_ver = NULL; + ver->txn.min_data_size = 0; ver->obj = NULL; page_cache_init_objver(ver); @@ -131,6 +133,9 @@ if (!ver) return; + ASSERT3P(ver->txn.txn, ==, NULL); + ASSERT3S(ver->txn.refcnt, ==, 0); + /* we shouldn't be freeing open objects */ for (i = 0; i < ARRAY_LEN(ver->open); i++) ASSERT3P(ver->open[i], ==, NULL); @@ -498,6 +503,8 @@ /* clear cow status */ open->cow.needed = false; + txn_detach_objver(txn, new); + return 0; } @@ -516,6 +523,8 @@ ASSERT3P(old->open[false], ==, open); ASSERT3P(new->open[false], ==, NULL); + txn_detach_objver(txn, new); + objver_free(new); } @@ -528,9 +537,9 @@ struct objver *old; int ret; - reset_objver_txn_info(txn, open->ver); + old = open->ver; - old = open->ver; + ASSERT3P(old->txn.txn, ==, NULL); if (!open->cow.needed) return old; @@ -548,8 +557,9 @@ new->obj = open->obj; new->clock = new_clock; new->attrs = old->attrs; - new->txn.cookie = old->txn.cookie; - new->txn.min_size = old->txn.min_size; + + txn_attach_objver(txn, new); + new->txn.prev_ver = old; /* add a txn entry */ entry = txn_alloc_entry(txn);
--- a/src/objstore/obj_txn.c Thu Dec 15 23:22:15 2022 -0500 +++ b/src/objstore/obj_txn.c Fri Dec 16 19:46:24 2022 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2020 Josef 'Jeff' Sipek <jeffpc@josefsipek.net> + * Copyright (c) 2015-2020,2022 Josef 'Jeff' Sipek <jeffpc@josefsipek.net> * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -64,8 +64,6 @@ size_t orig_len; int ret; - reset_objver_txn_info(NULL, ver); - if (offset >= ver->attrs.size) return 0; @@ -98,10 +96,15 @@ static int __obj_setattr_perform(struct txn *txn, struct txn_entry *entry) { struct objver *ver = entry->setattr.ver; + int ret; - return ver->obj->ops->setattr(ver, - &ver->attrs, - entry->setattr.changed); + ret = ver->obj->ops->setattr(ver, + &ver->attrs, + entry->setattr.changed); + + txn_detach_objver(txn, ver); + + return ret; } static void __obj_setattr_cleanup(struct txn *txn, struct txn_entry *entry) @@ -109,6 +112,8 @@ struct objver *ver = entry->setattr.ver; ver->attrs = entry->setattr.old_attrs; + + txn_detach_objver(txn, ver); } void obj_setattr(struct txn *txn, struct objver *ver, const struct nattr *attrs, @@ -116,7 +121,7 @@ { struct txn_entry *entry; - reset_objver_txn_info(txn, ver); + txn_attach_objver(txn, ver); if (valid & OBJ_ATTR_SIZE) { const uint64_t old = p2roundup(ver->attrs.size, PAGE_SIZE); @@ -127,8 +132,9 @@ page_inval_range(ver, new / PAGE_SIZE, (old - new) / PAGE_SIZE); - /* keep track of the shortest truncation */ - ver->txn.min_size = MIN(ver->txn.min_size, attrs->size); + /* keep track of the shortest truncation so far */ + ver->txn.min_data_size = MIN(ver->txn.min_data_size, + attrs->size); } entry = txn_alloc_entry(txn); @@ -194,12 +200,16 @@ page_unlock(page); } + txn_detach_objver(txn, ver); + return 0; err: /* drop the remaining dirty pages */ page_inval_range(ver, pgno, last_pgno - pgno + 1); + txn_detach_objver(txn, ver); + return ret; } @@ -208,6 +218,8 @@ /* drop the dirty pages */ page_inval_range(entry->write.ver, entry->write.pgno, entry->write.pgcnt); + + txn_detach_objver(txn, entry->write.ver); } /* write an arbitrary number of bytes */ @@ -222,7 +234,7 @@ ASSERT3U(offset, <, ver->attrs.size); ASSERT3U(offset + len, <=, ver->attrs.size); - reset_objver_txn_info(txn, ver); + txn_attach_objver(txn, ver); entry = txn_alloc_entry(txn); entry->op = OP_WRITE;
--- a/src/objstore/objstore_impl.h Thu Dec 15 23:22:15 2022 -0500 +++ b/src/objstore/objstore_impl.h Fri Dec 16 19:46:24 2022 -0500 @@ -135,6 +135,37 @@ return err; } +static inline void txn_attach_objver(struct txn *txn, struct objver *ver) +{ + if (ver->txn.txn == txn) { + ver->txn.refcnt++; + return; /* already attached */ + } + + ASSERT3P(ver->txn.txn, ==, NULL); + ASSERT3S(ver->txn.refcnt, ==, 0); + + ver->txn.txn = txn; + ver->txn.refcnt = 1; + ver->txn.prev_ver = NULL; + ver->txn.min_data_size = ver->attrs.size; +} + +static inline void txn_detach_objver(struct txn *txn, struct objver *ver) +{ + ASSERT3P(ver->txn.txn, ==, txn); + ASSERT3S(ver->txn.refcnt, >, 0); + + ver->txn.refcnt--; + if (ver->txn.refcnt) + return; + + ver->txn.txn = NULL; + ver->txn.refcnt = 0; + ver->txn.prev_ver = NULL; + ver->txn.min_data_size = 0; +} + /* * page-based cache */ @@ -150,17 +181,6 @@ #define page_lock(page) do { } while (0) #define page_unlock(page) do { } while (0) -static inline void reset_objver_txn_info(struct txn *txn, struct objver *ver) -{ - uint64_t cookie = txn ? txn->id : UINT64_MAX; - - if (ver->txn.cookie == cookie) - return; - - ver->txn.cookie = cookie; - ver->txn.min_size = ver->attrs.size; -} - REFCNT_INLINE_FXNS(struct obj, obj, refcnt, obj_free, NULL); #endif