[PATCH 12/14] Add ngnfs_dir_mkdir() and debugfs command

Valerie Aurora val at versity.com
Thu Feb 27 06:16:21 PST 2025


Makes a directory of the specified name in the current working
directory in debugfs.

Signed-off-by: Valerie Aurora <val at versity.com>
---
 cli/debugfs.c | 21 +++++++++++++++++++++
 shared/dir.c  | 44 ++++++++++++++++++++++++++++++++++++++++++++
 shared/dir.h  |  2 ++
 3 files changed, 67 insertions(+)

diff --git a/cli/debugfs.c b/cli/debugfs.c
index 9816247..fd6e2f0 100644
--- a/cli/debugfs.c
+++ b/cli/debugfs.c
@@ -126,6 +126,26 @@ static void cmd_lookup(struct debugfs_context *ctx, int argc, char **argv)
 	       le64_to_cpu(dent->version));
 }
 
+static void cmd_mkdir(struct debugfs_context *ctx, int argc, char **argv)
+{
+	int ret;
+
+	if (argc != 2) {
+		printf("must have one, and only one, directory name to create\n");
+		return;
+	}
+
+	ret = ngnfs_dir_mkdir(ctx->nfi, ctx->cwd_ino, 0755, argv[1], strlen(argv[1]));
+	if (ret == -EEXIST) {
+		printf("mkdir: file exists\n");
+		return;
+	}
+	if (ret < 0) {
+		log("mkdir error: "ENOF"\n", ENOA(-ret));
+		return;
+	}
+}
+
 static void cmd_mkfs(struct debugfs_context *ctx, int argc, char **argv)
 {
 	int ret;
@@ -261,6 +281,7 @@ static struct command {
 	{ "cd", cmd_cd, },
 	{ "create", cmd_create, },
 	{ "lookup", cmd_lookup, },
+	{ "mkdir", cmd_mkdir, },
 	{ "mkfs", cmd_mkfs, },
 	{ "quit", cmd_quit, },
 	{ "readdir", cmd_readdir, },
diff --git a/shared/dir.c b/shared/dir.c
index 5e825a4..87356ed 100644
--- a/shared/dir.c
+++ b/shared/dir.c
@@ -307,6 +307,50 @@ out:
 	return ret;
 }
 
+/*
+ * Create a new directory and add a directory entry referencing it.
+ */
+int ngnfs_dir_mkdir(struct ngnfs_fs_info *nfi, u64 dir_ino, umode_t mode, char *name,
+		    size_t name_len)
+{
+	struct {
+		struct ngnfs_transaction txn;
+		struct ngnfs_inode_txn_ref dir;
+		struct ngnfs_inode_txn_ref new_dir;
+		u64 ino;
+		u64 nsec;
+		struct dirent_args da;
+	} *op;
+	int ret;
+
+	op = kmalloc(sizeof(*op), GFP_NOFS);
+	if (!op) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	ngnfs_txn_init(&op->txn);
+	op->nsec = ktime_to_ns(ktime_get_real());
+	init_dirent_args(&op->da, name, name_len, 0, mode | S_IFDIR);
+
+	do {
+		ret = ngnfs_inode_get(nfi, &op->txn, NBF_WRITE, dir_ino, &op->dir)		?:
+		      check_ifmt(op->dir.ninode, S_IFDIR, -ENOTDIR)				?:
+		      ngnfs_inode_alloc(nfi, &op->txn, &op->ino, &op->new_dir)			?:
+		      ngnfs_inode_init(&op->new_dir, op->ino, 1, 2, mode | S_IFDIR, op->nsec,
+				       dir_ino)							?:
+		      update_dirent_args_ino(&op->da, op->ino)					?:
+		      insert_dirent(nfi, &op->txn, &op->dir, &op->da)				?:
+		      update_dir(op->dir.tblk, op->dir.ninode, &op->da, 1);
+
+	} while (ngnfs_txn_retry(nfi, &op->txn, &ret));
+
+	ngnfs_txn_teardown(nfi, &op->txn);
+	kfree(op);
+out:
+	return ret;
+}
+
 struct readdir_args {
 	struct ngnfs_readdir_entry *ent;
 	size_t size;
diff --git a/shared/dir.h b/shared/dir.h
index e15ab5f..0115411 100644
--- a/shared/dir.h
+++ b/shared/dir.h
@@ -6,6 +6,8 @@
 
 int ngnfs_dir_create(struct ngnfs_fs_info *nfi, u64 dir_ino, umode_t mode, char *name,
 		     size_t name_len);
+int ngnfs_dir_mkdir(struct ngnfs_fs_info *nfi, u64 dir_ino, umode_t mode, char *name,
+		    size_t name_len);
 
 /*
  * ngnfs_dir_get_handle() returns a thing that lets userspace clients do
-- 
2.48.1




More information about the ngnfs-devel mailing list