Mercurial > nomad > experimental
changeset 1260:a2e7e70338eb
objstore: rewrite obj_create to return the new object's objver
This will allow us to perform other operations (e.g., write) on the newly
allocated object in the same transation.
Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author | Josef 'Jeff' Sipek <jeffpc@josefsipek.net> |
---|---|
date | Sat, 17 Dec 2022 13:29:59 -0500 |
parents | eb4cc36f8ed1 |
children | 6d515779ac45 |
files | src/objstore/include/nomad/objstore_backend.h src/objstore/obj.c src/objstore/obj_dir_create.c src/objstore/objstore_impl.h |
diffstat | 4 files changed, 95 insertions(+), 21 deletions(-) [+] |
line wrap: on
line diff
--- a/src/objstore/include/nomad/objstore_backend.h Sat Dec 17 14:35:28 2022 -0500 +++ b/src/objstore/include/nomad/objstore_backend.h Sat Dec 17 13:29:59 2022 -0500 @@ -146,10 +146,8 @@ struct objver *new; } cow; struct { - struct noid oid; + struct objver *ver; struct noid parent; - struct nvclock clock; - struct nattr attrs; } create; struct { struct objver *ver;
--- a/src/objstore/obj.c Sat Dec 17 14:35:28 2022 -0500 +++ b/src/objstore/obj.c Sat Dec 17 13:29:59 2022 -0500 @@ -476,34 +476,102 @@ static int __obj_create_perform(struct txn *txn, struct txn_entry *entry) { - return txn->clone->ops->createobj(txn->clone, - &entry->create.oid, - &entry->create.clock, - &entry->create.attrs, - &entry->create.parent); + struct objver *ver = entry->create.ver; + int ret; + + ret = txn->clone->ops->createobj(txn->clone, + &ver->obj->oid, + &ver->clock, + &ver->attrs, + &entry->create.parent); + if (ret) + return ret; + + return 0; +} + +static void __obj_create_rollback(struct txn *txn, struct txn_entry *entry) +{ + panic("can't rollback transaction, must free obj"); + /* + * TODO: we must mark obj as dead and remove it from the + * volume + */ +} + +static void __obj_create_cleanup(struct txn *txn, struct txn_entry *entry) +{ + struct objver *ver = entry->create.ver; + + txn_detach_objver(txn, ver); + + MXUNLOCK(&ver->obj->lock); + + obj_putref(ver->obj); } -int obj_create(struct txn *txn, const struct nattr *attrs, - struct noid *oid, const struct noid *parent) +struct objver *obj_create(struct txn *txn, const struct nattr *attrs, + const struct noid *parent) { struct txn_entry *entry; + struct objver *ver; + struct obj *obj; + struct noid oid; int ret; - ret = txn->clone->ops->allocoid(txn->clone, oid); + ret = txn->clone->ops->allocoid(txn->clone, &oid); if (ret) - return ret; + return ERR_PTR(ret); + + ASSERT(!noid_is_null(&oid)); + + /* + * allocate a new object + * + * FIXME: triggers lockdep recursive locking warning (we're holding + * the dir's lock and are trying to get the child's lock) + */ + obj = obj_by_oid(txn->clone, &oid, true); + if (IS_ERR(obj)) + return ERR_CAST(obj); + + /* allocate a new version - must match obj_add_version */ + ver = objver_alloc(); + if (IS_ERR(ver)) { + panic("failed to allocate objver, must free obj"); + /* + * TODO: we must mark obj as dead and remove it from the + * volume + */ + MXUNLOCK(&obj->lock); + obj_putref(obj); + return ver; + } + + ver->obj = obj; + VERIFY0(nvclock_inc(&ver->clock)); + ver->attrs = *attrs; + + /* associate the version with the new object */ + rb_add(&obj->versions, ver); + __add_head(obj, ver); + + txn_attach_objver(txn, ver); + ver->txn.min_data_size = 0; /* there is no data prior to creation */ + + /* get a reference for the txn entry */ + obj_getref(obj); entry = txn_alloc_entry(txn); entry->op = OP_CREATE; entry->perform = __obj_create_perform; - entry->create.oid = *oid; - nvclock_reset(&entry->create.clock); - VERIFY0(nvclock_inc(&entry->create.clock)); - entry->create.attrs = *attrs; + entry->rollback = __obj_create_rollback; + entry->cleanup = __obj_create_cleanup; + entry->create.ver = ver; entry->create.parent = *parent; txn_log_entry(txn, entry); - return 0; + return ver; } static int __obj_cow_perform(struct txn *txn, struct txn_entry *entry)
--- a/src/objstore/obj_dir_create.c Sat Dec 17 14:35:28 2022 -0500 +++ b/src/objstore/obj_dir_create.c Sat Dec 17 13:29:59 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 @@ -41,8 +41,16 @@ .owner = owner, .group = group, }; + struct objver *ver; - return obj_create(txn, &attrs, oid, parent); + ver = obj_create(txn, &attrs, parent); + if (IS_ERR(ver)) + return PTR_ERR(ver); + + *oid = ver->obj->oid; + obj_putref(ver->obj); + + return 0; } static int __dir_create_add_dirent(struct txn *txn, struct objver *dirver,
--- a/src/objstore/objstore_impl.h Sat Dec 17 14:35:28 2022 -0500 +++ b/src/objstore/objstore_impl.h Sat Dec 17 13:29:59 2022 -0500 @@ -85,8 +85,8 @@ /* 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 struct objver *obj_create(struct txn *txn, const struct nattr *attrs, + 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,