btrfs: avoid overhead when logging messages if fs state is clean

If the fs state does not have any errors and is not in some special state
(like emergency shutdown or mounted with rescue options), then in
btrfs_state_to_string() we end up doing a memcpy() into the buffer and
then later just undo that work by setting the buffer's first element to
the NUL terminator, since fs_info->fs_error is 0 and there is no bit set
in fs_info->fs_state.

Improve on this by returning early if there's no error in the fs and the
fs state is clean, which is the expected scenario for a healthy fs that is
not mounted with special options like the rescue options.

Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
Filipe Manana 2026-09-30 12:09:43 +01:00 committed by David Sterba
parent 719aee8396
commit 22bdddf40e

View File

@ -33,27 +33,27 @@ static const char fs_state_chars[] = {
static void btrfs_state_to_string(const struct btrfs_fs_info *info, char *buf)
{
unsigned int bit;
bool states_printed = false;
unsigned long fs_state = READ_ONCE(info->fs_state);
char *curr = buf;
if (likely(BTRFS_FS_ERROR(info) == 0 && fs_state == 0)) {
*curr = 0;
return;
}
memcpy(curr, STATE_STRING_PREFACE, sizeof(STATE_STRING_PREFACE));
curr += sizeof(STATE_STRING_PREFACE) - 1;
if (unlikely(BTRFS_FS_ERROR(info))) {
if (BTRFS_FS_ERROR(info))
*curr++ = 'E';
states_printed = true;
}
for_each_set_bit(bit, &fs_state, BTRFS_FS_STATE_COUNT) {
if (fs_state_chars[bit]) {
if (fs_state_chars[bit])
*curr++ = fs_state_chars[bit];
states_printed = true;
}
}
/* If no states were printed, reset the buffer */
if (!states_printed)
/* If nothing printed, ensure we return an empty string. */
if (curr == (buf + sizeof(STATE_STRING_PREFACE) - 1))
curr = buf;
*curr = 0;