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;