U-Boot Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Kuan-Wei Chiu <visitorckw@gmail.com>
To: trini@konsulko.com, bmeng.cn@gmail.com, joe.hershberger@ni.com,
	rfried.dev@gmail.com, jerome.forissier@arm.com
Cc: jserv@ccns.ncku.edu.tw, eleanor15x@gmail.com,
	marscheng@google.com, u-boot@lists.denx.de,
	Kuan-Wei Chiu <visitorckw@gmail.com>
Subject: [PATCH 2/4] fs: 9p: Add 9P filesystem support
Date: Mon,  6 Jul 2026 21:54:44 +0000	[thread overview]
Message-ID: <20260706215446.4068820-3-visitorckw@gmail.com> (raw)
In-Reply-To: <20260706215446.4068820-1-visitorckw@gmail.com>

Implement the VFS interface for the 9P filesystem.

Map the U-Boot filesystem operations to the underlying 9P protocol
client. It also registers the 9P filesystem type within the U-Boot
generic fs framework, allowing it to bypass standard block device
partition checks since 9P is a network/host-backed filesystem.

Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
---
 fs/9p/9p.c     | 137 +++++++++++++++++++++++++++++++++++++++++++++++++
 fs/9p/Kconfig  |   8 +++
 fs/9p/Makefile |   5 ++
 fs/Kconfig     |   2 +
 fs/Makefile    |   1 +
 fs/fs.c        |  35 +++++++++++++
 include/fs.h   |   1 +
 7 files changed, 189 insertions(+)
 create mode 100644 fs/9p/9p.c
 create mode 100644 fs/9p/Kconfig
 create mode 100644 fs/9p/Makefile

diff --git a/fs/9p/9p.c b/fs/9p/9p.c
new file mode 100644
index 00000000000..37d60c03891
--- /dev/null
+++ b/fs/9p/9p.c
@@ -0,0 +1,137 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2026, Kuan-Wei Chiu <visitorckw@gmail.com>
+ */
+
+#include <9p.h>
+#include <config.h>
+#include <log.h>
+#include <asm/unaligned.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+
+static u32 p9_root_fid = 1;
+
+int p9_fs_probe(struct blk_desc *fs_dev_desc, struct disk_partition *fs_partition)
+{
+	struct p9_client *c = p9_get_client();
+
+	if (!c) {
+		log_err("9P Error: No transport client registered\n");
+		return -ENODEV;
+	}
+
+	if (p9_client_version(c))
+		return -EIO;
+	if (p9_client_attach(c, p9_root_fid, "root", ""))
+		return -EIO;
+
+	return 0;
+}
+
+int p9_fs_ls(const char *dirname)
+{
+	struct p9_client *c = p9_get_client();
+	u32 fid = p9_client_alloc_fid(c);
+	u8 buf[4096];
+	u32 actread;
+	u8 *ptr, *end;
+	u16 name_len;
+	u8 d_type;
+
+	if (p9_client_walk(c, p9_root_fid, fid, dirname))
+		return -ENOENT;
+	if (p9_client_lopen(c, fid, P9_O_RDONLY))
+		return -EIO;
+
+	if (p9_client_readdir(c, fid, 0, sizeof(buf), buf, &actread)) {
+		p9_client_clunk(c, fid);
+		return -EIO;
+	}
+
+	if (actread == 0) {
+		printf("  (empty directory)\n");
+	} else {
+		ptr = buf;
+		end = buf + actread;
+		while (ptr < end) {
+			ptr += P9_DIRENT_OFFSET;
+			d_type = *ptr++;
+			name_len = get_unaligned_le16(ptr);
+			ptr += 2;
+			printf("  %s %.*s\n", (d_type == P9_DT_DIR) ? "<DIR> " : "      ",
+			       name_len, ptr);
+			ptr += name_len;
+		}
+	}
+
+	p9_client_clunk(c, fid);
+	return 0;
+}
+
+int p9_fs_size(const char *filename, loff_t *size)
+{
+	struct p9_client *c = p9_get_client();
+	u32 fid = p9_client_alloc_fid(c);
+	int ret;
+
+	if (p9_client_walk(c, p9_root_fid, fid, filename))
+		return -ENOENT;
+	ret = p9_client_stat(c, fid, size);
+	p9_client_clunk(c, fid);
+
+	return ret;
+}
+
+int p9_fs_exists(const char *filename)
+{
+	loff_t size;
+
+	return (p9_fs_size(filename, &size) == 0) ? 1 : 0;
+}
+
+int p9_fs_read(const char *filename, void *buf, loff_t offset, loff_t len, loff_t *actread)
+{
+	struct p9_client *c = p9_get_client();
+	u32 fid = p9_client_alloc_fid(c);
+	u32 read_bytes = 0;
+	loff_t total_read = 0;
+	loff_t remaining;
+	u32 req_len;
+	u8 *dst = (u8 *)buf;
+	int ret = 0;
+
+	if (p9_client_walk(c, p9_root_fid, fid, filename))
+		return -ENOENT;
+	if (p9_client_lopen(c, fid, P9_O_RDONLY)) {
+		p9_client_clunk(c, fid);
+		return -EIO;
+	}
+
+	while (1) {
+		if (len == 0) {
+			req_len = 0;
+		} else {
+			remaining = len - total_read;
+			if (remaining == 0)
+				break;
+
+			req_len = (remaining > 0xFFFFFFFF) ? 0xFFFFFFFF : (u32)remaining;
+		}
+
+		ret = p9_client_read(c, fid, offset, req_len, dst, &read_bytes);
+
+		if (ret != 0 || read_bytes == 0)
+			break;
+
+		total_read += read_bytes;
+		offset += read_bytes;
+		dst += read_bytes;
+	}
+
+	*actread = total_read;
+	p9_client_clunk(c, fid);
+
+	return (total_read > 0 || ret == 0) ? 0 : ret;
+}
diff --git a/fs/9p/Kconfig b/fs/9p/Kconfig
new file mode 100644
index 00000000000..bc6d4962288
--- /dev/null
+++ b/fs/9p/Kconfig
@@ -0,0 +1,8 @@
+config FS_9P
+	bool "9P filesystem support"
+	depends on NET_9P
+	help
+	  This provides support for the 9P2000.L filesystem.
+
+	  To use this filesystem, you also need to enable a 9P
+	  transport driver.
diff --git a/fs/9p/Makefile b/fs/9p/Makefile
new file mode 100644
index 00000000000..c7f7553e8f4
--- /dev/null
+++ b/fs/9p/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Copyright (C) 2026, Kuan-Wei Chiu <visitorckw@gmail.com>
+
+obj-y += 9p.o
diff --git a/fs/Kconfig b/fs/Kconfig
index e0b0b901e1d..e4aa726ea35 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -26,4 +26,6 @@ source "fs/squashfs/Kconfig"
 
 source "fs/erofs/Kconfig"
 
+source "fs/9p/Kconfig"
+
 endmenu
diff --git a/fs/Makefile b/fs/Makefile
index ce5e74257a0..5aa34b39172 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -26,5 +26,6 @@ obj-$(CONFIG_CMD_UBIFS) += ubifs/
 obj-$(CONFIG_CMD_ZFS) += zfs/
 obj-$(CONFIG_FS_SQUASHFS) += squashfs/
 obj-$(CONFIG_FS_EROFS) += erofs/
+obj-$(CONFIG_FS_9P) += 9p/
 endif
 obj-y += fs_internal.o
diff --git a/fs/fs.c b/fs/fs.c
index 8ea50a6c13c..0bb996dede5 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -32,6 +32,7 @@
 #include <squashfs.h>
 #include <erofs.h>
 #include <exfat.h>
+#include <9p.h>
 
 static struct blk_desc *fs_dev_desc;
 static int fs_dev_part;
@@ -398,6 +399,26 @@ static struct fstype_info fstypes[] = {
 		.mkdir = exfat_fs_mkdir,
 		.rename = exfat_fs_rename,
 	},
+#endif
+#if CONFIG_IS_ENABLED(FS_9P)
+	{
+		.fstype = FS_TYPE_9P,
+		.name = "9p",
+		.null_dev_desc_ok = true,
+		.probe = p9_fs_probe,
+		.close = fs_close_unsupported,
+		.ls = p9_fs_ls,
+		.exists = p9_fs_exists,
+		.size = p9_fs_size,
+		.read = p9_fs_read,
+		.write = fs_write_unsupported,
+		.uuid = fs_uuid_unsupported,
+		.opendir = fs_opendir_unsupported,
+		.unlink = fs_unlink_unsupported,
+		.mkdir = fs_mkdir_unsupported,
+		.ln = fs_ln_unsupported,
+		.rename = fs_rename_unsupported,
+	},
 #endif
 	{
 		.fstype = FS_TYPE_ANY,
@@ -464,6 +485,20 @@ int fs_set_blk_dev(const char *ifname, const char *dev_part_str, int fstype)
 	struct fstype_info *info;
 	int part, i;
 
+	/* Intercept 9p to bypass block device partition checks */
+	if (CONFIG_IS_ENABLED(FS_9P) && !strncmp(ifname, "9p", 2)) {
+		for (i = 0, info = fstypes; i < ARRAY_SIZE(fstypes); i++, info++) {
+			if (info->fstype == FS_TYPE_9P) {
+				fs_dev_desc = NULL;
+				fs_type = FS_TYPE_9P;
+				if (info->probe(fs_dev_desc, NULL))
+					return -1;
+				return 0;
+			}
+		}
+		return -1;
+	}
+
 	part = part_get_info_by_dev_and_name_or_num(ifname, dev_part_str, &fs_dev_desc,
 						    &fs_partition, 1);
 	if (part < 0)
diff --git a/include/fs.h b/include/fs.h
index bec02117737..8afc81c0017 100644
--- a/include/fs.h
+++ b/include/fs.h
@@ -19,6 +19,7 @@ struct cmd_tbl;
 #define FS_TYPE_EROFS   7
 #define FS_TYPE_SEMIHOSTING 8
 #define FS_TYPE_EXFAT   9
+#define FS_TYPE_9P      10
 
 struct blk_desc;
 
-- 
2.55.0.rc2.803.g1fd1e6609c-goog


  parent reply	other threads:[~2026-07-06 21:55 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-06 21:54 [PATCH 0/4] fs: Add 9P filesystem support over virtio Kuan-Wei Chiu
2026-07-06 21:54 ` [PATCH 1/4] net: 9p: Add 9P2000 protocol support Kuan-Wei Chiu
2026-07-15 18:42   ` Simon Glass
2026-07-06 21:54 ` Kuan-Wei Chiu [this message]
2026-07-15 18:42   ` [PATCH 2/4] fs: 9p: Add 9P filesystem support Simon Glass
2026-07-06 21:54 ` [PATCH 3/4] virtio: 9p: Add 9P transport driver Kuan-Wei Chiu
2026-07-15 18:42   ` Simon Glass
2026-07-06 21:54 ` [PATCH 4/4] MAINTAINERS: Add entry for 9PFS Kuan-Wei Chiu
2026-07-15 18:42   ` Simon Glass
2026-07-07 16:44 ` [PATCH 0/4] fs: Add 9P filesystem support over virtio Tom Rini
2026-07-15 18:42 ` [0/4] " Simon Glass

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260706215446.4068820-3-visitorckw@gmail.com \
    --to=visitorckw@gmail.com \
    --cc=bmeng.cn@gmail.com \
    --cc=eleanor15x@gmail.com \
    --cc=jerome.forissier@arm.com \
    --cc=joe.hershberger@ni.com \
    --cc=jserv@ccns.ncku.edu.tw \
    --cc=marscheng@google.com \
    --cc=rfried.dev@gmail.com \
    --cc=trini@konsulko.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox