Mercurial > nomad
view src/objstore/objstore_impl.h @ 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 | c8ed13a24e47 |
children | 8ccfc441cff6 |
line wrap: on
line source
/* * 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 * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #ifndef __OBJSTORE_IMPL_H #define __OBJSTORE_IMPL_H #include <jeffpc/mem.h> #include <jeffpc/list.h> #include <nomad/objstore.h> #include <nomad/objstore_backend.h> /* backend support */ struct backend { struct list_node node; const struct objstore_vdev_def *def; void *module; }; enum pg_find_flags { PG_ALLOC = 0x01, PG_FILL = 0x02, }; struct page { union { struct rb_node node; /* in-use: objver pages tree */ struct list pages; /* free: internal page list */ }; struct objver *objver; uint64_t pgno; uint8_t *ptr; bool inuse:1; /* used by an object version */ bool filled:1; /* contains data */ bool dirty:1; /* must be written back */ }; /* internal backend management */ extern struct backend *backend_lookup(const char *name); /* internal volume management */ extern int vol_init(void); extern void vol_fini(void); extern int vol_import(struct objstore_clone *clone); /* internal vdev management */ extern int vdev_init(void); extern void vdev_fini(void); /* internal object management */ extern struct mem_cache *obj_cache; extern struct mem_cache *objver_cache; extern struct mem_cache *open_obj_cache; extern void obj_free(struct obj *obj); /* internal object version management */ extern struct objver *objver_alloc(void); extern void objver_free(struct objver *ver); extern struct obj *obj_by_oid(struct objstore_clone *clone, const struct noid *oid); extern struct objver *objver_by_clock(struct objstore_clone *clone, const struct noid *oid, const struct nvclock *clock); /* add various transaction ops to the transaction */ extern struct objver *obj_cow(struct txn *txn, struct objstore_open_obj_info *open); extern int obj_create(struct txn *txn, const struct nattr *attrs, struct noid *oid, const struct noid *parent); extern ssize_t obj_read(struct objver *ver, void *buf, size_t len, uint64_t offset); extern void obj_setattr(struct txn *txn, struct objver *ver, const struct nattr *attrs, unsigned valid); extern ssize_t obj_write(struct txn *txn, struct objver *ver, const void *buf, size_t len, uint64_t offset); /* read/manipulate a directory */ extern int dir_lookup_one(struct objver *dirver, const char *name, const struct noid *desired, struct noid *child, uint8_t *type); extern ssize_t dir_lookup_all(struct objver *dirver, const char *name, struct noid **child, uint8_t **type); extern int dir_getdent(struct objver *dirver, const uint64_t offset, struct ndirent *child); extern int dir_create(struct txn *txn, struct objver *dirver, const char *name, uint32_t owner, uint32_t group, uint16_t mode, struct noid *child); extern int dir_unlink(struct txn *txn, struct objver *dirver, const char *name, const struct noid *desired); /* * Each transaction starts with a begin call and ends with a commit or abort * call. If commit fails, it aborts the transaction internally. * * While a transaction is open, calls to txn_alloc_entry allocate space for * an operation to be performed by the transaction. This call does not * fail. * * If an error is encountered during a transaction, make sure to leave each * entry as either fully initialized or as a no-op (OP_NOP). Then, call * abort which will rollback up any non-nop entries. */ extern int txn_begin(struct txn *txn, struct objstore_clone *clone); extern int txn_commit(struct txn *txn); extern void txn_abort(struct txn *txn); extern struct txn_entry *txn_alloc_entry(struct txn *txn); extern void txn_log_entry(struct txn *txn, struct txn_entry *entry); static inline int txn_commitabort(struct txn *txn, int err) { if (!err) return txn_commit(txn); txn_abort(txn); 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 */ extern int page_cache_init(size_t max_size); extern void page_cache_free(void); extern void page_cache_init_objver(struct objver *ver); extern void page_cache_deinit_objver(struct objver *ver); extern struct page *page_lookup(struct objver *ver, uint64_t pgno, int flags); extern void page_inval_range(struct objver *ver, uint64_t pgno, size_t pgcnt); /* for now, we rely on the obj lock */ #define page_lock(page) do { } while (0) #define page_unlock(page) do { } while (0) REFCNT_INLINE_FXNS(struct obj, obj, refcnt, obj_free, NULL); #endif