[Concept,10/16] ext4l: Add exists() support

Message ID 20251227204318.886983-11-sjg@u-boot.org
State New
Headers
Series fs: ext4l: Complete read-only filesystem support (Part I) |

Commit Message

Simon Glass Dec. 27, 2025, 8:43 p.m. UTC
  From: Simon Glass <simon.glass@canonical.com>

Implement ext4l_exists() to check if a file or directory exists on the
filesystem. This uses ext4l_resolve_path() to look up the path and
returns 1 if found, 0 otherwise.

Wire the function into fs_legacy.c and add a basic test.

Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
---

 fs/ext4l/interface.c                | 13 +++++++++++++
 fs/fs_legacy.c                      |  2 +-
 include/ext4l.h                     |  8 ++++++++
 test/fs/ext4l.c                     | 27 +++++++++++++++++++++++++++
 test/py/tests/test_fs/test_ext4l.py |  7 +++++++
 5 files changed, 56 insertions(+), 1 deletion(-)
  

Patch

diff --git a/fs/ext4l/interface.c b/fs/ext4l/interface.c
index e7f09fd45dc..409a3ff7edc 100644
--- a/fs/ext4l/interface.c
+++ b/fs/ext4l/interface.c
@@ -636,6 +636,19 @@  int ext4l_ls(const char *dirname)
 	return ret;
 }
 
+int ext4l_exists(const char *filename)
+{
+	struct inode *inode;
+
+	if (!filename)
+		return 0;
+
+	if (ext4l_resolve_path(filename, &inode))
+		return 0;
+
+	return 1;
+}
+
 void ext4l_close(void)
 {
 	if (ext4l_open_dirs > 0)
diff --git a/fs/fs_legacy.c b/fs/fs_legacy.c
index 7d293468ea8..849c0304668 100644
--- a/fs/fs_legacy.c
+++ b/fs/fs_legacy.c
@@ -266,7 +266,7 @@  static struct fstype_info fstypes[] = {
 		.probe = ext4l_probe,
 		.close = ext4l_close,
 		.ls = ext4l_ls,
-		.exists = fs_exists_unsupported,
+		.exists = ext4l_exists,
 		.size = fs_size_unsupported,
 		.read = fs_read_unsupported,
 		.write = fs_write_unsupported,
diff --git a/include/ext4l.h b/include/ext4l.h
index 6d8eba84f4e..23d53b30d9e 100644
--- a/include/ext4l.h
+++ b/include/ext4l.h
@@ -38,6 +38,14 @@  void ext4l_close(void);
  */
 int ext4l_ls(const char *dirname);
 
+/**
+ * ext4l_exists() - Check if a file or directory exists
+ *
+ * @filename: Path to check
+ * Return: 1 if exists, 0 if not
+ */
+int ext4l_exists(const char *filename);
+
 /**
  * ext4l_get_uuid() - Get the filesystem UUID
  *
diff --git a/test/fs/ext4l.c b/test/fs/ext4l.c
index d9ed21407e7..79813375ff1 100644
--- a/test/fs/ext4l.c
+++ b/test/fs/ext4l.c
@@ -196,3 +196,30 @@  static int fs_test_ext4l_opendir_norun(struct unit_test_state *uts)
 }
 FS_TEST_ARGS(fs_test_ext4l_opendir_norun, UTF_SCAN_FDT | UTF_CONSOLE |
 	     UTF_MANUAL, { "fs_image", UT_ARG_STR });
+
+/**
+ * fs_test_ext4l_exists_norun() - Test ext4l_exists function
+ *
+ * Verifies that ext4l_exists correctly reports file existence.
+ *
+ * Arguments:
+ *   fs_image: Path to the ext4 filesystem image
+ */
+static int fs_test_ext4l_exists_norun(struct unit_test_state *uts)
+{
+	const char *fs_image = ut_str(EXT4L_ARG_IMAGE);
+
+	ut_assertnonnull(fs_image);
+	ut_assertok(run_commandf("host bind 0 %s", fs_image));
+	ut_assertok(fs_set_blk_dev("host", "0", FS_TYPE_ANY));
+
+	/* Test existing directory */
+	ut_asserteq(1, ext4l_exists("/"));
+
+	/* Test non-existent paths */
+	ut_asserteq(0, ext4l_exists("/no/such/path"));
+
+	return 0;
+}
+FS_TEST_ARGS(fs_test_ext4l_exists_norun, UTF_SCAN_FDT | UTF_CONSOLE |
+	     UTF_MANUAL, { "fs_image", UT_ARG_STR });
diff --git a/test/py/tests/test_fs/test_ext4l.py b/test/py/tests/test_fs/test_ext4l.py
index 073b02a80ce..890b6aeaef1 100644
--- a/test/py/tests/test_fs/test_ext4l.py
+++ b/test/py/tests/test_fs/test_ext4l.py
@@ -96,3 +96,10 @@  class TestExt4l:
             output = ubman.run_command(
                 f'ut -f fs fs_test_ext4l_opendir_norun fs_image={ext4_image}')
             assert 'failures: 0' in output
+
+    def test_exists(self, ubman, ext4_image):
+        """Test that ext4l_exists reports file existence correctly."""
+        with ubman.log.section('Test ext4l exists'):
+            output = ubman.run_command(
+                f'ut -f fs fs_test_ext4l_exists_norun fs_image={ext4_image}')
+            assert 'failures: 0' in output