changeset 1185:facc1b5299a8

objstore/posix: create_obj can construct empty directories by itself Instead of constructing them in the generic code and passing the buffer in somehow, we can construct them in the backend by calling the generic obj_make_dir_buffer. As a side effect, we get a nice simplification of create_rootdir as well. Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
date Mon, 06 Apr 2020 22:22:49 -0400
parents af90ba985ab9
children 054a740303bf
files src/objstore/posix/obj_create.c src/objstore/posix/posix.h src/objstore/posix/vol.c
diffstat 3 files changed, 45 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/src/objstore/posix/obj_create.c	Mon Apr 06 22:17:21 2020 -0400
+++ b/src/objstore/posix/obj_create.c	Mon Apr 06 22:22:49 2020 -0400
@@ -90,22 +90,45 @@
 	return ret;
 }
 
-static int create_obj_with_data(int rootfd, uint64_t host, uint64_t uniq,
+static int create_obj_with_data(int rootfd,
+				uint64_t this_host, uint64_t this_uniq,
+				uint64_t parent_host, uint64_t parent_uniq,
 				const struct nvclock *clock,
-				const struct nattr *attrs,
-				struct buffer *contents)
+				const struct nattr *_attrs)
 {
+	struct buffer contents;
+	struct nattr attrs;
 	char objname[34];
 	int ret;
 	int fd;
 
+	attrs = *_attrs;
+
+	/* create empty directory contents for new directories */
+	if (NATTR_ISDIR(attrs.mode)) {
+		ret = buffer_init_heap(&contents, BLOCK_SIZE); /* size guess */
+		if (ret)
+			return ret;
+
+		ret = obj_make_dir_buffer(this_host, this_uniq, parent_host,
+					  parent_uniq, &contents);
+		if (ret)
+			goto err;
+
+		/* overwrite the requested size */
+		attrs.size = buffer_size(&contents);
+	} else {
+		/* initialize the buffer to make buffer_free work */
+		buffer_init_sink(&contents);
+	}
+
 	snprintf(objname, sizeof(objname), "%016"PRIx64"-%016"PRIx64,
-		 host, uniq);
+		 this_host, this_uniq);
 
 	/* create the object directory */
 	ret = xmkdirat(rootfd, objname, 0700);
 	if (ret)
-		return ret;
+		goto err;
 
 	/* open the object directory */
 	fd = xopenat(rootfd, objname, O_RDONLY, 0);
@@ -115,12 +138,15 @@
 	}
 
 	/* create the object version file */
-	ret = create_objver(fd, clock, attrs, contents);
+	ret = create_objver(fd, clock, &attrs,
+			    NATTR_ISDIR(attrs.mode) ? &contents : NULL);
 	if (ret)
 		goto err_close;
 
 	xclose(fd);
 
+	buffer_free(&contents);
+
 	return ret;
 
 err_close:
@@ -129,14 +155,18 @@
 err_unlink:
 	xunlinkat(rootfd, objname, 0);
 
+err:
+	buffer_free(&contents);
+
 	return ret;
 }
 
-/* create any object - its contents will be empty */
 int create_obj(int rootfd, uint64_t host, uint64_t uniq,
+	       uint64_t parent_host, uint64_t parent_uniq,
 	       const struct nvclock *clock, const struct nattr *attrs)
 {
-	return create_obj_with_data(rootfd, host, uniq, clock, attrs, NULL);
+	return create_obj_with_data(rootfd, host, uniq, parent_host,
+				    parent_uniq, clock, attrs);
 }
 
 /* create a root directory */
@@ -146,7 +176,7 @@
 	struct nattr attrs = {
 		.mode  = NATTR_DIR | 0700,
 		.nlink = 1, /* even new dirs have a link count of 1 */
-		.size  = 0, /* overwritten below */
+		.size  = 0, /* overwritten in create_obj */
 		.atime = now,
 		.btime = now,
 		.ctime = now,
@@ -154,27 +184,10 @@
 		.owner = 0,
 		.group = 0,
 	};
-	struct buffer *contents;
 	struct nvclock clock;
-	int ret;
 
 	nvclock_reset(&clock);
 	VERIFY0(nvclock_inc(&clock));
 
-	contents = buffer_alloc(BLOCK_SIZE); /* guessing the size */
-	if (IS_ERR(contents))
-		return PTR_ERR(contents);
-
-	ret = obj_make_dir_buffer(host, uniq, host, uniq, contents);
-	if (ret)
-		goto err;
-
-	attrs.size = buffer_size(contents);
-
-	ret = create_obj_with_data(rootfd, host, uniq, &clock, &attrs, contents);
-
-err:
-	buffer_free(contents);
-
-	return ret;
+	return create_obj(rootfd, host, uniq, host, uniq, &clock, &attrs);
 }
--- a/src/objstore/posix/posix.h	Mon Apr 06 22:17:21 2020 -0400
+++ b/src/objstore/posix/posix.h	Mon Apr 06 22:22:49 2020 -0400
@@ -161,6 +161,7 @@
 extern const struct clone_ops posix_clone_ops;
 
 extern int create_obj(int rootfd, uint64_t host, uint64_t uniq,
+		      uint64_t parent_host, uint64_t parent_uniq,
 		      const struct nvclock *clock, const struct nattr *attrs);
 extern int create_rootdir(int rootfd, uint64_t host, uint64_t uniq);
 
--- a/src/objstore/posix/vol.c	Mon Apr 06 22:17:21 2020 -0400
+++ b/src/objstore/posix/vol.c	Mon Apr 06 22:22:49 2020 -0400
@@ -103,8 +103,10 @@
 {
 	struct posix_vol *pvol = clone->private;
 
-	return create_obj(pvol->rootfd, noid_get_allocator(oid),
-			  noid_get_uniq(oid), clock, attrs);
+	return create_obj(pvol->rootfd,
+			  noid_get_allocator(oid), noid_get_uniq(oid),
+			  noid_get_allocator(parent), noid_get_uniq(parent),
+			  clock, attrs);
 }
 
 const struct clone_ops posix_clone_ops = {