diff --git a/cmd/Kconfig b/cmd/Kconfig index 5cb34509746..d602f430ab6 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -2839,6 +2839,16 @@ config CMD_FS_UUID help Enables fsuuid command for filesystem UUID. +config CMD_FSINFO + bool "fsinfo command" + depends on !CMD_JFFS2 + default y if SANDBOX + help + Enables the fsinfo command which prints filesystem statistics + such as block size, total blocks, used blocks and free blocks. + This command conflicts with the JFFS2 fsinfo command, so it + cannot be enabled when JFFS2 support is enabled. + config CMD_LUKS bool "luks command" depends on BLK_LUKS diff --git a/cmd/fs.c b/cmd/fs.c index 7058f17b24f..960fd024c75 100644 --- a/cmd/fs.c +++ b/cmd/fs.c @@ -152,3 +152,17 @@ U_BOOT_CMD( " - renames/moves a file/directory in 'dev' on 'interface' from\n" " 'old_path' to 'new_path'" ); + +#ifdef CONFIG_CMD_FSINFO +static int do_fsinfo_wrapper(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + return do_fs_statfs(cmdtp, flag, argc, argv); +} + +U_BOOT_CMD(fsinfo, 3, 1, do_fsinfo_wrapper, + "Print filesystem information", + " \n" + " - Print filesystem statistics (block size, total/used/free blocks)" +); +#endif diff --git a/doc/usage/cmd/fsinfo.rst b/doc/usage/cmd/fsinfo.rst new file mode 100644 index 00000000000..5129a9a29b9 --- /dev/null +++ b/doc/usage/cmd/fsinfo.rst @@ -0,0 +1,53 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +.. index:: + single: fsinfo (command) + +fsinfo command +============== + +Synopsis +-------- + +:: + + fsinfo + +Description +----------- + +The fsinfo command displays filesystem statistics for a partition including +block size, total blocks, used blocks, and free blocks. Both raw byte counts +and human-readable sizes are shown. + +interface + interface for accessing the block device (mmc, sata, scsi, usb, ....) + +dev + device number + +part + partition number, defaults to 1 + +Example +------- + +:: + + => fsinfo mmc 0:1 + Block size: 4096 bytes + Total blocks: 16384 (67108864 bytes, 64 MiB) + Used blocks: 2065 (8458240 bytes, 8.1 MiB) + Free blocks: 14319 (58650624 bytes, 55.9 MiB) + +Configuration +------------- + +The fsinfo command is only available if CONFIG_CMD_FS_GENERIC=y. + +Return value +------------ + +The return value $? is set to 0 (true) if the command succeeded and to 1 +(false) otherwise. If the filesystem does not support statfs, an error +message is displayed. diff --git a/doc/usage/index.rst b/doc/usage/index.rst index bbea78a17b2..6c1414a0b84 100644 --- a/doc/usage/index.rst +++ b/doc/usage/index.rst @@ -81,6 +81,7 @@ Shell commands cmd/fdt cmd/font cmd/for + cmd/fsinfo cmd/fwu_mdata cmd/gpio cmd/gpt diff --git a/fs/fs_legacy.c b/fs/fs_legacy.c index e8a5f8d9672..efb5ab669ff 100644 --- a/fs/fs_legacy.c +++ b/fs/fs_legacy.c @@ -1105,6 +1105,38 @@ int do_fs_type(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) return CMD_RET_SUCCESS; } +int do_fs_statfs(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) +{ + struct fs_statfs st; + u64 used; + int ret; + + if (argc != 3) + return CMD_RET_USAGE; + + if (fs_set_blk_dev(argv[1], argv[2], FS_TYPE_ANY)) + return 1; + + ret = fs_statfs(&st); + if (ret) { + printf("** Filesystem info not supported **\n"); + return CMD_RET_FAILURE; + } + + used = st.blocks - st.bfree; + printf("Block size: %lu bytes\n", st.bsize); + printf("Total blocks: %llu (%llu bytes, ", st.blocks, + st.blocks * st.bsize); + print_size(st.blocks * st.bsize, ")\n"); + printf("Used blocks: %llu (%llu bytes, ", used, used * st.bsize); + print_size(used * st.bsize, ")\n"); + printf("Free blocks: %llu (%llu bytes, ", st.bfree, + st.bfree * st.bsize); + print_size(st.bfree * st.bsize, ")\n"); + + return 0; +} + int do_rm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[], int fstype) { diff --git a/include/fs_cmd.h b/include/fs_cmd.h index 3b58ad516e7..b28799d5ae4 100644 --- a/include/fs_cmd.h +++ b/include/fs_cmd.h @@ -80,4 +80,15 @@ int do_fs_type(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); */ int do_fs_types(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]); +/** + * do_fs_statfs - Get filesystem statistics. + * + * @cmdtp: Command information for fsinfo + * @flag: Command flags (CMD_FLAG\_...) + * @argc: Number of arguments + * @argv: List of arguments + * Return: result (see enum command_ret_t) + */ +int do_fs_statfs(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); + #endif diff --git a/test/fs/ext4l.c b/test/fs/ext4l.c index 02ad13ec71d..2641ac3678c 100644 --- a/test/fs/ext4l.c +++ b/test/fs/ext4l.c @@ -327,3 +327,30 @@ static int fs_test_ext4l_uuid_norun(struct unit_test_state *uts) } FS_TEST_ARGS(fs_test_ext4l_uuid_norun, UTF_SCAN_FDT | UTF_CONSOLE | UTF_MANUAL, { "fs_image", UT_ARG_STR }); + +/** + * fs_test_ext4l_fsinfo_norun() - Test fsinfo command + * + * This test verifies that the fsinfo command displays filesystem statistics. + * + * Arguments: + * fs_image: Path to the ext4 filesystem image + */ +static int fs_test_ext4l_fsinfo_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)); + console_record_reset_enable(); + ut_assertok(run_commandf("fsinfo host 0")); + ut_assert_nextlinen("Block size:"); + ut_assert_nextlinen("Total blocks:"); + ut_assert_nextlinen("Used blocks:"); + ut_assert_nextlinen("Free blocks:"); + ut_assert_console_end(); + + return 0; +} +FS_TEST_ARGS(fs_test_ext4l_fsinfo_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 2bbbe766e6a..0a9da40f358 100644 --- a/test/py/tests/test_fs/test_ext4l.py +++ b/test/py/tests/test_fs/test_ext4l.py @@ -124,3 +124,10 @@ class TestExt4l: output = ubman.run_command( f'ut -f fs fs_test_ext4l_uuid_norun fs_image={ext4_image}') assert 'failures: 0' in output + + def test_fsinfo(self, ubman, ext4_image): + """Test that fsinfo command displays filesystem statistics.""" + with ubman.log.section('Test ext4l fsinfo'): + output = ubman.run_command( + f'ut -f fs fs_test_ext4l_fsinfo_norun fs_image={ext4_image}') + assert 'failures: 0' in output