Mercurial > nomad > experimental
changeset 285:a680d8b9436d
objstore: unlink object op should take a struct objver
Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author | Josef 'Jeff' Sipek <jeffpc@josefsipek.net> |
---|---|
date | Tue, 26 Apr 2016 17:32:17 -0400 |
parents | ccb58952784f |
children | a20cca3b00b2 |
files | src/objstore/include/nomad/objstore_backend.h src/objstore/include/nomad/objstore_impl.h src/objstore/mem/obj.c src/objstore/obj.c src/objstore/vg.c |
diffstat | 5 files changed, 68 insertions(+), 64 deletions(-) [+] |
line wrap: on
line diff
--- a/src/objstore/include/nomad/objstore_backend.h Tue Apr 26 17:32:17 2016 -0400 +++ b/src/objstore/include/nomad/objstore_backend.h Tue Apr 26 17:32:17 2016 -0400 @@ -101,8 +101,8 @@ struct noid *child); int (*create)(struct objver *dirver, const char *name, uint16_t mode, struct noid *child); - int (*unlink)(struct objstore_vol *vol, void *dircookie, - const char *name); + int (*unlink)(struct objver *dirver, const char *name, + struct obj *child); /* * Called just before the generic object is freed.
--- a/src/objstore/include/nomad/objstore_impl.h Tue Apr 26 17:32:17 2016 -0400 +++ b/src/objstore/include/nomad/objstore_impl.h Tue Apr 26 17:32:17 2016 -0400 @@ -65,8 +65,4 @@ REFCNT_INLINE_FXNS(struct obj, obj, refcnt, freeobj); -/* wrappers for object ops */ -extern int vol_unlink(struct objstore_vol *vol, void *dircookie, - const char *name); - #endif
--- a/src/objstore/mem/obj.c Tue Apr 26 17:32:17 2016 -0400 +++ b/src/objstore/mem/obj.c Tue Apr 26 17:32:17 2016 -0400 @@ -260,16 +260,25 @@ * We don't do I/O, instead we keep everything in memory. This however * means that instead of doing I/O (which would write generic object and * object version state to disk) we need to copy the generic state into our - * private backend structures. + * private backend structures. We accomplish this using two helper + * functions: + * + * sync_obj_to_mobj + * sync_ver_to_mver */ +static void sync_obj_to_mobj(struct obj *obj) +{ + struct memobj *mobj = obj->private; + + mobj->nlink = obj->nlink; +} + static void sync_ver_to_mver(struct objver *ver) { - struct memobj *mobj = ver->obj->private; struct memver *mver = ver->private; - struct obj *obj = ver->obj; /* object */ - mobj->nlink = obj->nlink; + sync_obj_to_mobj(ver->obj); /* version */ nvclock_copy(mver->clock, ver->clock); @@ -561,13 +570,10 @@ return 0; } -static int __obj_unlink(struct memstore *store, struct memver *dir, - struct memdentry *dentry) +static void __obj_unlink(struct memver *dir, struct memdentry *dentry, + struct obj *child) { - struct memobj *child; - - /* get a reference for us */ - child = memobj_getref(dentry->obj); + VERIFY3P(child->private, ==, dentry->obj); /* remove the dentry from the directory */ avl_remove(&dir->dentries, dentry); @@ -575,52 +581,39 @@ /* free the dentry */ freedentry(dentry); - /* if there are no more links to the child obj, free it */ - if (!--child->nlink) { - mxlock(&store->lock); - avl_remove(&store->objs, child); - mxunlock(&store->lock); + child->nlink--; + + sync_obj_to_mobj(child); +} - /* put the global list's ref */ - memobj_putref(child); - } +static int mem_obj_unlink(struct objver *dirver, const char *name, + struct obj *child) +{ + const struct memdentry key = { + .name = name, + }; + struct memver *dirmver = dirver->private; + struct memdentry *dentry; - /* put our ref */ - memobj_putref(child); + dentry = avl_find(&dirmver->dentries, &key, NULL); + if (!dentry) + return -ENOENT; + + /* ok, we got the dentry - remove it */ + __obj_unlink(dirmver, dentry, child); /* * We changed the dir, so we need to up the version. * * TODO: do we need to tweak the versions AVL tree? */ - nvclock_inc(dir->clock); + nvclock_inc(dirver->clock); + + sync_ver_to_mver(dirver); return 0; } -static int mem_obj_unlink(struct objstore_vol *vol, void *dircookie, - const char *name) -{ - const struct memdentry key = { - .name = name, - }; - struct memdentry *dentry; - struct memver *dirver = dircookie; - struct memstore *ms; - - if (!vol || !dirver || !name) - return -EINVAL; - - ms = vol->private; - - dentry = avl_find(&dirver->dentries, &key, NULL); - if (!dentry) - return -ENOENT; - - /* ok, we got the dentry - remove it */ - return __obj_unlink(ms, dirver, dentry); -} - const struct obj_ops obj_ops = { .getversion = mem_obj_getversion, .open = mem_obj_open,
--- a/src/objstore/obj.c Tue Apr 26 17:32:17 2016 -0400 +++ b/src/objstore/obj.c Tue Apr 26 17:32:17 2016 -0400 @@ -30,17 +30,6 @@ umem_cache_t *obj_cache; umem_cache_t *objver_cache; -int vol_unlink(struct objstore_vol *vol, void *dircookie, const char *name) -{ - if (!vol || !name) - return -EINVAL; - - if (!vol->def->obj_ops || !vol->def->obj_ops->unlink) - return -ENOTSUP; - - return vol->def->obj_ops->unlink(vol, dircookie, name); -} - static int ver_cmp(const void *va, const void *vb) { const struct objver *a = va;
--- a/src/objstore/vg.c Tue Apr 26 17:32:17 2016 -0400 +++ b/src/objstore/vg.c Tue Apr 26 17:32:17 2016 -0400 @@ -658,6 +658,18 @@ return ret; } +static struct obj *getobj_in_dir(struct objver *dirver, const char *name) +{ + struct noid child_oid; + int ret; + + ret = dirver->obj->ops->lookup(dirver, name, &child_oid); + if (ret) + return ERR_PTR(ret); + + return getobj(dirver->obj->vol->vg, &child_oid); +} + int objstore_unlink(struct objstore *vg, void *dircookie, const char *name) { struct objver *dirver = dircookie; @@ -674,11 +686,25 @@ dir = dirver->obj; + if (!dir->ops || !dir->ops->unlink || !dir->ops->lookup) + return -ENOTSUP; + mxlock(&dir->lock); - if (!NATTR_ISDIR(dirver->attrs.mode)) + if (!NATTR_ISDIR(dirver->attrs.mode)) { ret = -ENOTDIR; - else - ret = vol_unlink(dir->vol, dir->open_cookie, name); + } else { + struct obj *child; + + child = getobj_in_dir(dirver, name); + if (!IS_ERR(child)) { + ret = dir->ops->unlink(dirver, name, child); + + mxunlock(&child->lock); + obj_putref(child); + } else { + ret = PTR_ERR(child); + } + } mxunlock(&dir->lock); return ret;