Skip to content

Commit 25f665e

Browse files
committed
btrfs-progs: fi commit-stats: add new command
Signed-off-by: David Sterba <dsterba@suse.com>
1 parent b4518c0 commit 25f665e

File tree

3 files changed

+141
-1
lines changed

3 files changed

+141
-1
lines changed

Documentation/btrfs-filesystem.rst

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,26 @@ show [options] [<path>|<uuid>|<device>|<label>]
334334
--tbytes
335335
show sizes in TiB, or TB with --si
336336

337+
commit-stats
338+
Print number of commits and time stats since mount. This is also available
339+
in :file:`/sys/fs/btrfs/FSID/commit_stats`. The stats are not persistent
340+
and are collected since mount of the filesystem, one of them can be reset
341+
to zero (*Max commit duration*).
342+
343+
.. code-block:: none
344+
345+
UUID: bd18ebe1-7e1d-414f-a3d5-2644388b51cc
346+
Commit stats since mount:
347+
Total commits: 1133
348+
Last commit duration: 0ms
349+
Max commit duration: 10ms
350+
Total time spent in commit: 4543ms
351+
352+
``Options``
353+
354+
-z|--reset
355+
print stats and reset 'max_commit_ms' (needs root)
356+
337357
sync <path>
338358
Force a sync of the filesystem at *path*, similar to the :manref:`sync(1)` command. In
339359
addition, it starts cleaning of deleted subvolumes. To wait for the subvolume

btrfs-completion

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ _btrfs()
2424

2525
commands='subvolume filesystem balance device scrub check rescue restore inspect-internal property send receive quota qgroup replace help version'
2626
commands_subvolume='create delete list snapshot find-new get-default set-default show sync'
27-
commands_filesystem='defragment sync resize show df du label usage mkswapfile'
27+
commands_filesystem='defragment sync resize show df du label usage mkswapfile commit-stats'
2828
commands_balance='start pause cancel resume status'
2929
commands_device='scan add delete remove ready stats usage'
3030
commands_scrub='start cancel resume status'

cmds/filesystem.c

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1970,6 +1970,125 @@ static int cmd_filesystem_mkswapfile(const struct cmd_struct *cmd, int argc, cha
19701970
}
19711971
static DEFINE_SIMPLE_COMMAND(filesystem_mkswapfile, "mkswapfile");
19721972

1973+
static const char * const cmd_filesystem_commit_stats_usage[] = {
1974+
"btrfs filesystem commit-stats <file>",
1975+
"Print number of commits and time stats since mount",
1976+
"",
1977+
OPTLINE("-z|--reset", "print stats and reset 'max_commit_ms' (needs root)"),
1978+
NULL
1979+
};
1980+
1981+
static int cmd_filesystem_commit_stats(const struct cmd_struct *cmd, int argc, char **argv)
1982+
{
1983+
int ret;
1984+
int fd = -1;
1985+
int sysfs_fd = -1;
1986+
char buf[64 * 1024];
1987+
char *tmp, *ptr, *savepos = NULL;
1988+
uuid_t fsid;
1989+
bool opt_reset = false;
1990+
static const struct {
1991+
const char *key;
1992+
const char *desc;
1993+
const char *units;
1994+
} str2str[] = {
1995+
{ "commits", "Total commits:", NULL },
1996+
{ "last_commit_ms", "Last commit duration:", "ms" },
1997+
{ "max_commit_ms", "Max commit duration:", "ms" },
1998+
{ "total_commit_ms", "Total time spent in commit:", "ms" },
1999+
};
2000+
2001+
optind = 0;
2002+
while (1) {
2003+
int c;
2004+
static const struct option long_options[] = {
2005+
{ "reset", no_argument, NULL, 'z' },
2006+
{ NULL, 0, NULL, 0 }
2007+
};
2008+
2009+
c = getopt_long(argc, argv, "c", long_options, NULL);
2010+
if (c < 0)
2011+
break;
2012+
switch (c) {
2013+
case 'z':
2014+
opt_reset = true;
2015+
break;
2016+
default:
2017+
usage_unknown_option(cmd, argv);
2018+
}
2019+
}
2020+
2021+
if (check_argc_min(argc - optind, 1))
2022+
return 1;
2023+
2024+
fd = btrfs_open_dir(argv[optind]);
2025+
if (fd < 0)
2026+
return 1;
2027+
2028+
sysfs_fd = sysfs_open_fsid_file(fd, "commit_stats");
2029+
if (sysfs_fd < 0) {
2030+
error("no commit_stats file in sysfs");
2031+
goto out;
2032+
}
2033+
2034+
ret = sysfs_read_file(sysfs_fd, buf, sizeof(buf));
2035+
if (ret < 0) {
2036+
error("cannot read commit_stats: %m");
2037+
goto out;
2038+
}
2039+
2040+
ret = get_fsid_fd(fd, fsid);
2041+
/* Don't fail, sysfs_open_fsid_file() calls that as well. */
2042+
if (ret == 0) {
2043+
char fsid_str[BTRFS_UUID_UNPARSED_SIZE];
2044+
2045+
uuid_unparse(fsid, fsid_str);
2046+
pr_verbose(LOG_DEFAULT, "UUID: %s\n", fsid_str);
2047+
}
2048+
ptr = buf;
2049+
pr_verbose(LOG_DEFAULT, "Commit stats since mount:\n");
2050+
while (1) {
2051+
const char *units = NULL;
2052+
2053+
tmp = strtok_r(ptr, " \n", &savepos);
2054+
ptr = NULL;
2055+
if (!tmp)
2056+
break;
2057+
2058+
for (int i = 0; i < ARRAY_SIZE(str2str); i++) {
2059+
if (strcmp(tmp, str2str[i].key) == 0) {
2060+
tmp = (char *)str2str[i].desc;
2061+
units = str2str[i].units;
2062+
break;
2063+
}
2064+
}
2065+
/* Print unknown as-is */
2066+
pr_verbose(LOG_DEFAULT, " %-28s", tmp);
2067+
2068+
tmp = strtok_r(ptr, " \n", &savepos);
2069+
if (!tmp)
2070+
break;
2071+
pr_verbose(LOG_DEFAULT, "%8s%s", tmp, (units ?: ""));
2072+
putchar('\n');
2073+
}
2074+
2075+
if (opt_reset) {
2076+
close(sysfs_fd);
2077+
ret = sysfs_write_fsid_file_u64(fd, "commit_stats", 0);
2078+
if (ret < 0)
2079+
warning("cannot reset stats: %m");
2080+
else
2081+
pr_verbose(LOG_DEFAULT, "NOTE: Max commit duration has been reset\n");
2082+
}
2083+
2084+
out:
2085+
close(sysfs_fd);
2086+
close(fd);
2087+
2088+
return 0;
2089+
}
2090+
static DEFINE_SIMPLE_COMMAND(filesystem_commit_stats, "commit-stats");
2091+
19732092
static const char filesystem_cmd_group_info[] =
19742093
"overall filesystem tasks and information";
19752094

@@ -1978,6 +2097,7 @@ static const struct cmd_group filesystem_cmd_group = {
19782097
&cmd_struct_filesystem_df,
19792098
&cmd_struct_filesystem_du,
19802099
&cmd_struct_filesystem_show,
2100+
&cmd_struct_filesystem_commit_stats,
19812101
&cmd_struct_filesystem_sync,
19822102
&cmd_struct_filesystem_defrag,
19832103
&cmd_struct_filesystem_balance,

0 commit comments

Comments
 (0)