From patchwork Sat Dec 27 20:43:10 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 1092 Return-Path: X-Original-To: u-boot-concept@u-boot.org Delivered-To: u-boot-concept@u-boot.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1766868293; bh=cPyPZcBTQJFssAXUqtmcZ+UV9aOi2IkPF4W3UaRwGtQ=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=CgstXc28cWyYx/a09r60+SxVJlH6aQS6zfz3+hpLdcTpSeyCVYgW81hkjWJFEYQpU Uh+XQ2ZZaxvGlJkfFtW8SGDWiX9sGT2/VgtkBTFI+MO6ZaWioCFoKgjqRmfppWxU8h TdIpfMhQAy5LvI+X8m8uzDzjqJ633C09/HEsg2h37srjmUj1jWBEk61aFu/EQJH2iS BfTae2HwzcJ0TknahJ89sGMbkB86Q13/fhvG0CwLX/i5XfKyu4yYMpAZj5XEX5EzqC /U160Q+wzdf47T9tnTSvLRyu/x9XIHtGixRnN2xPsI/iDlqVKdIpDei7vLFBR72nCI xUMA0GQQlBFhg== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 7ADA268BEF for ; Sat, 27 Dec 2025 13:44:53 -0700 (MST) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10024) with ESMTP id EFLjFwL1J-x0 for ; Sat, 27 Dec 2025 13:44:53 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1766868292; bh=cPyPZcBTQJFssAXUqtmcZ+UV9aOi2IkPF4W3UaRwGtQ=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=r9/3RTb88WG81cfPj02duvKzqJ8pqe4Dyg6EaWvNBZMp2ShOO0MBbhSfXc8iH0cPz lhRsnoMuNqH0OoMxQlOEVgyPdeWANClW6vo2ppGbJFeEn+xZoLZiqp5gnhr5lL6NI0 CUArlyCMBBb00cXlozxxFaLcANavsgXJ/+6X+237aydcMtlfAemrjyKSbyNUo3DH06 CR08y8HZzaLUObLzWTfLhuZ6frYCIM8EafWqYWq+qbRn9K21353peIpgpsl1LbnBfq 5pAHYcyCgbNJ8GmBOWuBiy8gySxmfhSrmUy/ebOoXLgX+DJXgRiwUVCFEfPXvzaqjr RB+DU3Zh5utzw== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 7823264E4D for ; Sat, 27 Dec 2025 13:44:52 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1766868290; bh=jNvhJrpOUrg1Jz/w6BOx4erbOgrKo71H+6nPx1Gr1jY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=YOJa2hnFw5U41zuOgiXjeLnBV6EWB10ch/geMqgoDJq1yyHI6EbWJAxDwjTCwTwxH gcck9oniP3O3zDRUW7fKrWSYqs9TlDpw6k/xqqU5MTw3PyTxw4HsffiJe5cVBINTzm y7iyz1sQte2qtUiS+5v/9Yt+KwbT1Xv4nWe2T8bihHzSe82gD5ytrgmHwV9zEpFQQf rgBTpYb3X8M+y86Bneg//Kcn4Eg6yBpJANfFSwMMGG5j8KoPCwLWDMh/9KNnoFpAS9 T/ZFC1Lq9iquO5Hkm9uezgIPc3ykwihc/XbTDG6nFj0z5QotoLsQzcA4aMtQdVCvzV BavZwgMtcbNsw== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id C6C1F64E44; Sat, 27 Dec 2025 13:44:50 -0700 (MST) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10026) with ESMTP id 0b5VQrcFL0NY; Sat, 27 Dec 2025 13:44:50 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1766868290; bh=6KZKz+F78cDnrtuCAr4ZNOUeuCIaCRrMPL9sv/aZxXY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=vLc7CtX9MUoxzM42dbd18i9V0dyxEj0/QBQWToMYJe4OZchouJte8jUYUoouLQEnx fQ2jaKRKCI/n2nHJgTcC4kGqe/Aob+dPXGyFBWPvqRc9M6WM68bEDMnG6NMyFCE6dB 0h4nrhTAf4sXwDF+uU0KuQfoiD7jQtsB4PWqG90zB96ZK9l8jGyrcgtfX0pav8QT5R Vh+0up5nU9rW1UeN6ySnmmU7lCgN18kfXevKgZZlTy+HeebjYdFu1c2NITy6yZvT/x nSDWFi03p93SK7L/gTHAwU6QRHv3ztInz/m1vJyLtvR8TJW3lf06V5QFyVuZTprZv/ LHYWoNWkccibQ== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id F1CFE64C0C; Sat, 27 Dec 2025 13:44:49 -0700 (MST) From: Simon Glass To: U-Boot Concept Date: Sat, 27 Dec 2025 13:43:10 -0700 Message-ID: <20251227204318.886983-16-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251227204318.886983-1-sjg@u-boot.org> References: <20251227204318.886983-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: 63J76PRGUWENAMWVCQOPIMJ7HSM2JU2V X-Message-ID-Hash: 63J76PRGUWENAMWVCQOPIMJ7HSM2JU2V X-MailFrom: sjg@u-boot.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Heinrich Schuchardt , Simon Glass , "Claude Opus 4 . 5" X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 15/16] cmd: Add fsinfo command List-Id: Discussion and patches related to U-Boot Concept Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Simon Glass Add the fsinfo command to display filesystem statistics including block size, total blocks, used blocks, and free blocks. Both raw byte counts and human-readable sizes are shown. Example output: => 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) Co-developed-by: Claude Opus 4.5 Signed-off-by: Simon Glass --- cmd/Kconfig | 10 ++++++ cmd/fs.c | 14 ++++++++ doc/usage/cmd/fsinfo.rst | 53 +++++++++++++++++++++++++++++ doc/usage/index.rst | 1 + fs/fs_legacy.c | 32 +++++++++++++++++ include/fs_cmd.h | 11 ++++++ test/fs/ext4l.c | 27 +++++++++++++++ test/py/tests/test_fs/test_ext4l.py | 7 ++++ 8 files changed, 155 insertions(+) create mode 100644 doc/usage/cmd/fsinfo.rst 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