[PATCH 05/14] Add support for dtype

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


From: Zach Brown <zab at zabbo.net>

Add dtype support to avoid unnecesary inode reads.

Co-authored-by: Valerie Aurora <val at versity.com>
Signed-off-by: Valerie Aurora <val at versity.com>
---
 cli/debugfs.c         |  6 ++---
 shared/dir.c          | 52 ++++++++++++++++++++++++++++++++++---------
 shared/dir.h          |  4 ++++
 shared/format-block.h | 12 +++++++++-
 shared/lk/fs_types.h  |  7 ++++++
 5 files changed, 66 insertions(+), 15 deletions(-)
 create mode 100644 shared/lk/fs_types.h

diff --git a/cli/debugfs.c b/cli/debugfs.c
index 3fc4c76..1972f13 100644
--- a/cli/debugfs.c
+++ b/cli/debugfs.c
@@ -12,7 +12,6 @@
 #include "shared/lk/byteorder.h"
 #include "shared/lk/err.h"
 #include "shared/lk/kernel.h"
-#include "shared/lk/timekeeping.h"
 #include "shared/lk/types.h"
 
 #include "shared/format-block.h"
@@ -22,7 +21,6 @@
 #include "shared/mkfs.h"
 #include "shared/mount.h"
 #include "shared/thread.h"
-#include "shared/txn.h"
 
 #include "cli/cli.h"
 
@@ -98,8 +96,8 @@ static void cmd_readdir(struct debugfs_context *ctx, int argc, char **argv)
 
 		ent = buf;
 		for (i = 0; i < ret; i++) {
-			printf("%020llu %10llu %5llu %.*s\n", ent->pos, ent->ino, ent->gen,
-			       ent->name_len, ent->name);
+			printf("%020llu %10llu %5llu %05o %.*s\n", ent->pos, ent->ino, ent->gen,
+			       ent->dtype, ent->name_len, ent->name);
 			pos = ent->pos;
 			ent = (void *)ent + ent->next_offset;
 		}
diff --git a/shared/dir.c b/shared/dir.c
index 6375f65..a0c698f 100644
--- a/shared/dir.c
+++ b/shared/dir.c
@@ -7,6 +7,7 @@
 #include "shared/lk/byteorder.h"
 #include "shared/lk/container_of.h"
 #include "shared/lk/errno.h"
+#include "shared/lk/fs_types.h"
 #include "shared/lk/kernel.h"
 #include "shared/lk/ktime.h"
 #include "shared/lk/limits.h"
@@ -53,7 +54,7 @@ static u64 name_hash(void *name, size_t name_len)
 struct dirent_args {
 	u64 hash;
 	size_t dent_size;
-	mode_t mode;
+	u8 dtype;
 	u64 ino;
 
 	struct ngnfs_dirent dent;
@@ -67,10 +68,41 @@ static void init_dirent_key(struct ngnfs_btree_key *key, u64 hash)
 	};
 }
 
-/* XXX :) */
-static u8 ngnfs_dt(umode_t mode)
+/* Convert a POSIX file mode to an ngnfs on-disk dirent type */
+static enum ngnfs_dentry_type mode_to_type(umode_t mode)
 {
-	return 0;
+#define S_SHIFT 12
+	static unsigned char mode_types[S_IFMT >> S_SHIFT] = {
+		[S_IFIFO >> S_SHIFT]	= NGNFS_DT_FIFO,
+		[S_IFCHR >> S_SHIFT]	= NGNFS_DT_CHR,
+		[S_IFDIR >> S_SHIFT]	= NGNFS_DT_DIR,
+		[S_IFBLK >> S_SHIFT]	= NGNFS_DT_BLK,
+		[S_IFREG >> S_SHIFT]	= NGNFS_DT_REG,
+		[S_IFLNK >> S_SHIFT]	= NGNFS_DT_LNK,
+		[S_IFSOCK >> S_SHIFT]	= NGNFS_DT_SOCK,
+	};
+
+	return mode_types[(mode & S_IFMT) >> S_SHIFT];
+#undef S_SHIFT
+}
+
+/* Convert the on-disk ngnfs dirent dtype to the POSIX d_type */
+unsigned int ngnfs_type_to_dtype(enum ngnfs_dentry_type type)
+{
+	static unsigned char types[] = {
+		[NGNFS_DT_FIFO]	= DT_FIFO,
+		[NGNFS_DT_CHR]	= DT_CHR,
+		[NGNFS_DT_DIR]	= DT_DIR,
+		[NGNFS_DT_BLK]	= DT_BLK,
+		[NGNFS_DT_REG]	= DT_REG,
+		[NGNFS_DT_LNK]	= DT_LNK,
+		[NGNFS_DT_SOCK]	= DT_SOCK,
+	};
+
+	if (type < ARRAY_SIZE(types))
+		return types[type];
+
+	return DT_UNKNOWN;
 }
 
 static void init_dirent_args(struct dirent_args *da, char *name, size_t name_len, u64 ino,
@@ -78,11 +110,11 @@ static void init_dirent_args(struct dirent_args *da, char *name, size_t name_len
 {
 	da->hash = name_hash(name, name_len);
 	da->dent_size = offsetof(struct ngnfs_dirent, name) + name_len;
-	da->mode = mode;
+	da->dtype = IFTODT(mode);
 
 	da->dent.ino = cpu_to_le64(ino);
 	da->dent.version = cpu_to_le64(0); /* XXX :/ */
-	da->dent.dtype = ngnfs_dt(mode);
+	da->dent.type = mode_to_type(mode);
 	da->dent.name_len = name_len;
 
 	/* ensure that we're stitching together a contiguous max name buffer */
@@ -118,7 +150,7 @@ static int update_dir(struct ngnfs_txn_block *tblk, struct ngnfs_inode *dir,
 	s32 delta;
 	int ret;
 
-	if (S_ISDIR(da->mode)) {
+	if (S_ISDIR(le32_to_cpu(dir->mode))) {
 		delta = posneg * 1;
 		if ((le32_to_cpu(dir->nlink) + delta >= NGNFS_LINK_MAX)) {
 			ret = -EMLINK;
@@ -222,13 +254,13 @@ int ngnfs_dir_create(struct ngnfs_fs_info *nfi, u64 dir_ino, umode_t mode, char
 
 	ngnfs_txn_init(&op->txn);
 	op->nsec = ktime_to_ns(ktime_get_real());
-	init_dirent_args(&op->da, name, name_len, 0, mode);
+	init_dirent_args(&op->da, name, name_len, 0, mode | S_IFREG);
 
 	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->inode)			?:
-		      ngnfs_inode_init(&op->inode, op->ino, 1, 1, mode, op->nsec)		?:
+		      ngnfs_inode_init(&op->inode, op->ino, 1, 1, mode | S_IFREG, op->nsec)	?:
 		      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);
@@ -264,7 +296,7 @@ static int fill_dirent_rd(struct ngnfs_btree_key *key, void *val, size_t val_siz
 	ra->ent->ino = le64_to_cpu(dent->ino);
 	ra->ent->gen = le64_to_cpu(dent->version);
 	ra->ent->next_offset = aligned;
-	ra->ent->dtype = 0;
+	ra->ent->dtype = ngnfs_type_to_dtype(dent->type);
 	ra->ent->name_len = dent->name_len;
 	memcpy(ra->ent->name, dent->name, dent->name_len);
 	ra->ent->name[ra->ent->name_len] = '\0';
diff --git a/shared/dir.h b/shared/dir.h
index 5594162..b333686 100644
--- a/shared/dir.h
+++ b/shared/dir.h
@@ -38,4 +38,8 @@ struct ngnfs_readdir_entry {
 int ngnfs_dir_readdir(struct ngnfs_fs_info *nfi, u64 dir_ino, u64 pos,
 		      struct ngnfs_readdir_entry *buf, size_t size);
 
+enum ngnfs_dentry_type;
+
+unsigned int ngnfs_type_to_dtype(enum ngnfs_dentry_type type);
+
 #endif
diff --git a/shared/format-block.h b/shared/format-block.h
index 83731bc..65274e1 100644
--- a/shared/format-block.h
+++ b/shared/format-block.h
@@ -112,10 +112,20 @@ struct ngnfs_inode {
  */
 #define NGNFS_LINK_MAX	S32_MAX
 
+enum ngnfs_dentry_type {
+	NGNFS_DT_FIFO = 0,
+	NGNFS_DT_CHR,
+	NGNFS_DT_DIR,
+	NGNFS_DT_BLK,
+	NGNFS_DT_REG,
+	NGNFS_DT_LNK,
+	NGNFS_DT_SOCK,
+};
+
 struct ngnfs_dirent {
 	__le64 ino;
 	__le64 version; /* XXX ? */
-	__u8 dtype;
+	__u8 type;
 	__u8 name_len; /* no null termination */
 	__u8 name[6]; /* definition pads to alignment, stored can be smaller */
 };
diff --git a/shared/lk/fs_types.h b/shared/lk/fs_types.h
new file mode 100644
index 0000000..5ab3d0a
--- /dev/null
+++ b/shared/lk/fs_types.h
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef NGNFS_SHARED_LK_FS_TYPES_H
+#define NGNFS_SHARED_LK_FS_TYPES_H
+
+#include <dirent.h>
+
+#endif /* _LINUX_FS_TYPES_H */
-- 
2.48.1




More information about the ngnfs-devel mailing list