[Concept,11/16] ext4l: Add size() support

Message ID 20251227204318.886983-12-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>

Add ext4l_size() function to retrieve the size of a file or directory.
Wire it into the filesystem operations table in fs_legacy.c.

Signed-off-by: Simon Glass <sjg@chromium.org>

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

 fs/ext4l/interface.c                | 14 ++++++++++++
 fs/fs_legacy.c                      |  2 +-
 include/ext4l.h                     |  9 ++++++++
 test/fs/ext4l.c                     | 34 +++++++++++++++++++++++++++++
 test/py/tests/test_fs/test_ext4l.py |  7 ++++++
 5 files changed, 65 insertions(+), 1 deletion(-)
  

Patch

diff --git a/fs/ext4l/interface.c b/fs/ext4l/interface.c
index 409a3ff7edc..17648a59077 100644
--- a/fs/ext4l/interface.c
+++ b/fs/ext4l/interface.c
@@ -649,6 +649,20 @@  int ext4l_exists(const char *filename)
 	return 1;
 }
 
+int ext4l_size(const char *filename, loff_t *sizep)
+{
+	struct inode *inode;
+	int ret;
+
+	ret = ext4l_resolve_path(filename, &inode);
+	if (ret)
+		return ret;
+
+	*sizep = inode->i_size;
+
+	return 0;
+}
+
 void ext4l_close(void)
 {
 	if (ext4l_open_dirs > 0)
diff --git a/fs/fs_legacy.c b/fs/fs_legacy.c
index 849c0304668..5edc35c4cdb 100644
--- a/fs/fs_legacy.c
+++ b/fs/fs_legacy.c
@@ -267,7 +267,7 @@  static struct fstype_info fstypes[] = {
 		.close = ext4l_close,
 		.ls = ext4l_ls,
 		.exists = ext4l_exists,
-		.size = fs_size_unsupported,
+		.size = ext4l_size,
 		.read = fs_read_unsupported,
 		.write = fs_write_unsupported,
 		.uuid = fs_uuid_unsupported,
diff --git a/include/ext4l.h b/include/ext4l.h
index 23d53b30d9e..6fee701f335 100644
--- a/include/ext4l.h
+++ b/include/ext4l.h
@@ -46,6 +46,15 @@  int ext4l_ls(const char *dirname);
  */
 int ext4l_exists(const char *filename);
 
+/**
+ * ext4l_size() - Get the size of a file
+ *
+ * @filename: Path to file
+ * @sizep: Returns the file size
+ * Return: 0 on success, negative on error
+ */
+int ext4l_size(const char *filename, loff_t *sizep);
+
 /**
  * ext4l_get_uuid() - Get the filesystem UUID
  *
diff --git a/test/fs/ext4l.c b/test/fs/ext4l.c
index 79813375ff1..f58a91893cc 100644
--- a/test/fs/ext4l.c
+++ b/test/fs/ext4l.c
@@ -11,6 +11,7 @@ 
 #include <ext4l.h>
 #include <fs.h>
 #include <fs_legacy.h>
+#include <linux/sizes.h>
 #include <u-boot/uuid.h>
 #include <test/test.h>
 #include <test/ut.h>
@@ -223,3 +224,36 @@  static int fs_test_ext4l_exists_norun(struct unit_test_state *uts)
 }
 FS_TEST_ARGS(fs_test_ext4l_exists_norun, UTF_SCAN_FDT | UTF_CONSOLE |
 	     UTF_MANUAL, { "fs_image", UT_ARG_STR });
+
+/**
+ * fs_test_ext4l_size_norun() - Test ext4l_size function
+ *
+ * Verifies that ext4l_size correctly reports file size.
+ *
+ * Arguments:
+ *   fs_image: Path to the ext4 filesystem image
+ */
+static int fs_test_ext4l_size_norun(struct unit_test_state *uts)
+{
+	const char *fs_image = ut_str(EXT4L_ARG_IMAGE);
+	loff_t size;
+
+	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 root directory size - one block on a 4K block filesystem */
+	ut_assertok(ext4l_size("/", &size));
+	ut_asserteq(SZ_4K, size);
+
+	/* Test file size - testfile.txt contains "hello world\n" */
+	ut_assertok(ext4l_size("/testfile.txt", &size));
+	ut_asserteq(12, size);
+
+	/* Test non-existent path returns -ENOENT */
+	ut_asserteq(-ENOENT, ext4l_size("/no/such/path", &size));
+
+	return 0;
+}
+FS_TEST_ARGS(fs_test_ext4l_size_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 890b6aeaef1..922fa37a7d8 100644
--- a/test/py/tests/test_fs/test_ext4l.py
+++ b/test/py/tests/test_fs/test_ext4l.py
@@ -103,3 +103,10 @@  class TestExt4l:
             output = ubman.run_command(
                 f'ut -f fs fs_test_ext4l_exists_norun fs_image={ext4_image}')
             assert 'failures: 0' in output
+
+    def test_size(self, ubman, ext4_image):
+        """Test that ext4l_size reports file size correctly."""
+        with ubman.log.section('Test ext4l size'):
+            output = ubman.run_command(
+                f'ut -f fs fs_test_ext4l_size_norun fs_image={ext4_image}')
+            assert 'failures: 0' in output