[PATCH 11/15] Add ngnfs_dir_mkdir() and debugfs command
Valerie Aurora
val at versity.com
Wed Mar 12 07:33:50 PDT 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 | 43 ++++++++++++++++++++++++++++++++++++++++---
shared/dir.h | 2 ++
3 files changed, 63 insertions(+), 3 deletions(-)
diff --git a/cli/debugfs.c b/cli/debugfs.c
index 0c0914c..3494070 100644
--- a/cli/debugfs.c
+++ b/cli/debugfs.c
@@ -118,6 +118,26 @@ static void cmd_lookup(struct debugfs_context *ctx, int argc, char **argv)
lent.ig.gen);
}
+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_ig, 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;
@@ -268,6 +288,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 074f998..ebeea01 100644
--- a/shared/dir.c
+++ b/shared/dir.c
@@ -261,11 +261,24 @@ static int insert_dirent(struct ngnfs_fs_info *nfi, struct ngnfs_transaction *tx
&last, insert_dirent_wr, da);
}
+/*
+ * Prevent creation of "." and "..", with appropriate error return codes.
+ */
+static int check_create_dots(u64 hash, mode_t mode)
+{
+ if ((hash != NGNFS_DIRENT_DOT_HASH) && (hash != NGNFS_DIRENT_DOT_DOT_HASH))
+ return 0;
+
+ if (S_ISDIR(mode))
+ return -EEXIST;
+ else
+ return -EISDIR;
+}
/*
* Allocate a new inode and add a directory entry referencing it.
*/
-int ngnfs_dir_create(struct ngnfs_fs_info *nfi, struct ngnfs_inode_ino_gen *dir, umode_t mode,
+static int do_create(struct ngnfs_fs_info *nfi, struct ngnfs_inode_ino_gen *dir, umode_t mode,
char *name, size_t name_len)
{
struct {
@@ -273,6 +286,8 @@ int ngnfs_dir_create(struct ngnfs_fs_info *nfi, struct ngnfs_inode_ino_gen *dir,
struct ngnfs_inode_txn_ref dir;
struct ngnfs_inode_txn_ref inode;
struct ngnfs_inode_ino_gen ig;
+ struct ngnfs_inode_ino_gen *parent_ig;
+ int nlink;
u64 nsec;
struct dirent_args da;
} *op;
@@ -286,13 +301,23 @@ int ngnfs_dir_create(struct ngnfs_fs_info *nfi, struct ngnfs_inode_ino_gen *dir,
ngnfs_txn_init(&op->txn);
op->nsec = ktime_to_ns(ktime_get_real());
- init_dirent_args(&op->da, name, name_len, mode | S_IFREG);
+ if (S_ISDIR(mode)) {
+ op->nlink = 2;
+ op->parent_ig = dir;
+ } else {
+ op->nlink = 1;
+ op->parent_ig = NULL;
+ }
+
+ init_dirent_args(&op->da, name, name_len, mode);
do {
ret = ngnfs_inode_get(nfi, &op->txn, NBF_WRITE, dir, &op->dir) ?:
check_ifmt(op->dir.ninode, S_IFDIR, -ENOTDIR) ?:
+ check_create_dots(op->da.hash, mode) ?:
ngnfs_inode_alloc(nfi, &op->txn, &op->ig, &op->inode) ?:
- ngnfs_inode_init(&op->inode, &op->ig, 1, mode | S_IFREG, op->nsec, NULL) ?:
+ ngnfs_inode_init(&op->inode, &op->ig, op->nlink, mode, op->nsec,
+ op->parent_ig) ?:
update_dirent_args_ig(&op->da, &op->ig) ?:
insert_dirent(nfi, &op->txn, &op->dir, &op->da) ?:
update_dir(op->dir.tblk, op->dir.ninode, &op->da, 1);
@@ -305,6 +330,18 @@ out:
return ret;
}
+int ngnfs_dir_create(struct ngnfs_fs_info *nfi, struct ngnfs_inode_ino_gen *dir, umode_t mode,
+ char *name, size_t name_len)
+{
+ return do_create(nfi, dir, mode | S_IFREG, name, name_len);
+}
+
+int ngnfs_dir_mkdir(struct ngnfs_fs_info *nfi, struct ngnfs_inode_ino_gen *dir, umode_t mode,
+ char *name, size_t name_len)
+{
+ return do_create(nfi, dir, mode | S_IFDIR, name, name_len);
+}
+
struct readdir_args {
struct ngnfs_readdir_entry *ent;
size_t size;
diff --git a/shared/dir.h b/shared/dir.h
index 178f53e..5dd57dd 100644
--- a/shared/dir.h
+++ b/shared/dir.h
@@ -8,6 +8,8 @@
int ngnfs_dir_create(struct ngnfs_fs_info *nfi, struct ngnfs_inode_ino_gen *dir, umode_t mode,
char *name, size_t name_len);
+int ngnfs_dir_mkdir(struct ngnfs_fs_info *nfi, struct ngnfs_inode_ino_gen *dir, umode_t mode,
+ char *name, size_t name_len);
/*
* Readdir fills the buffer with entries. The start of the buffer must
--
2.48.1
More information about the ngnfs-devel
mailing list