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 #include #include +#include #include #include #include @@ -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