changeset 858:6d515779ac45

objstore: use the returned create objver for dir contents Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
date Sat, 17 Dec 2022 14:55:52 -0500
parents a2e7e70338eb
children 79102a88827c
files src/objstore/obj_dir_create.c
diffstat 1 files changed, 55 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- a/src/objstore/obj_dir_create.c	Sat Dec 17 13:29:59 2022 -0500
+++ b/src/objstore/obj_dir_create.c	Sat Dec 17 14:55:52 2022 -0500
@@ -24,16 +24,16 @@
 
 #include <jeffpc/time.h>
 
-/* allocate a new oid - the child */
-static int __dir_create_allocoid(struct txn *txn, uint32_t owner, uint32_t group,
-				 uint16_t mode, struct noid *oid,
-				 const struct noid *parent)
+/* create a new object - the child */
+static struct objver *__dir_create(struct txn *txn, uint32_t owner,
+				   uint32_t group, uint16_t mode,
+				   const struct noid *parent)
 {
 	const uint64_t now = gettime();
 	struct nattr attrs = {
 		.mode = mode,
 		.nlink = 1, /* even new dirs start with link count of 1 */
-		.size = 0,
+		.size = NATTR_ISDIR(mode) ? DIR_BLOCK_SIZE : 0,
 		.atime = now,
 		.btime = now,
 		.ctime = now,
@@ -41,16 +41,8 @@
 		.owner = owner,
 		.group = group,
 	};
-	struct objver *ver;
 
-	ver = obj_create(txn, &attrs, parent);
-	if (IS_ERR(ver))
-		return PTR_ERR(ver);
-
-	*oid = ver->obj->oid;
-	obj_putref(ver->obj);
-
-	return 0;
+	return obj_create(txn, &attrs, parent);
 }
 
 static int __dir_create_add_dirent(struct txn *txn, struct objver *dirver,
@@ -201,9 +193,11 @@
 }
 
 int dir_create(struct txn *txn, struct objver *dirver, const char *name,
-	       uint32_t owner, uint32_t group, uint16_t mode, struct noid *child)
+	       uint32_t owner, uint32_t group, uint16_t mode,
+	       struct noid *_child)
 {
 	uint8_t raw[DIR_BLOCK_SIZE];
+	struct objver *child;
 	struct ndirent_mem ent;
 	bool update_existing;
 	uint16_t ndirents;
@@ -227,24 +221,52 @@
 		update_existing = true;
 	}
 
-	/* make new oid for the child */
-	ret = __dir_create_allocoid(txn, owner, group, mode, child,
-				    &dirver->obj->oid);
-	if (ret)
-		return ret;
+	/* create the child */
+	child = __dir_create(txn, owner, group, mode, &dirver->obj->oid);
+	if (IS_ERR(child))
+		return PTR_ERR(child);
+
+	/* if the child is a directory, write out empty directory contents */
+	if (NATTR_ISDIR(child->attrs.mode)) {
+		uint8_t raw[DIR_BLOCK_SIZE];
+		struct buffer contents;
+		ssize_t ret2;
+
+		buffer_init_static(&contents, raw, sizeof(raw), sizeof(raw),
+				   true);
 
-	ASSERT(!noid_is_null(child));
+		ret = obj_make_dir_buffer(noid_get_allocator(&child->obj->oid),
+					  noid_get_uniq(&child->obj->oid),
+					  noid_get_allocator(&dirver->obj->oid),
+					  noid_get_uniq(&dirver->obj->oid),
+					  &contents);
+		if (ret)
+			goto err;
+
+		ret2 = obj_write(txn, child, raw, sizeof(raw), 0);
+		if (ret2 < 0) {
+			ret = ret2;
+			goto err;
+		}
+
+		if (ret2 != sizeof(raw)) {
+			ret = -EIO;
+			goto err;
+		}
+	}
 
 	/* add dirent to parent dir */
 	if (!update_existing) {
-		ret = __dir_create_add_dirent(txn, dirver, name, mode, child);
+		ret = __dir_create_add_dirent(txn, dirver, name, mode,
+					      &child->obj->oid);
 		if (ret)
-			return ret;
+			goto err;
 	} else {
 		ret = __dir_create_update_dirent(txn, dirver, raw, diroff,
-						 ndirents, name, mode, child);
+						 ndirents, name, mode,
+						 &child->obj->oid);
 		if (ret)
-			return ret;
+			goto err;
 	}
 
 	/*
@@ -252,5 +274,12 @@
 	 * did we'd increment the parent dir's link count here.
 	 */
 
-	return 0;
+	*_child = child->obj->oid;
+
+	ret = 0;
+
+err:
+	obj_putref(child->obj);
+
+	return ret;
 }