Skip to content

Bugfix: Critical sysuser home directory creation failure with BTRFS_SUBVOLUME_HOME=yes on non-Btrfs paths#1609

Open
silverhadch wants to merge 3 commits intoshadow-maint:masterfrom
silverhadch:master
Open

Bugfix: Critical sysuser home directory creation failure with BTRFS_SUBVOLUME_HOME=yes on non-Btrfs paths#1609
silverhadch wants to merge 3 commits intoshadow-maint:masterfrom
silverhadch:master

Conversation

@silverhadch
Copy link
Copy Markdown
Contributor

@silverhadch silverhadch commented Apr 14, 2026

This fixes a critical bug. Previously, Btrfs subvolume creation was only applied on-demand, but now it's forced for all users whenever BTRFS_SUBVOLUME_HOME=yes is set. That logic is too aggressive: it causes system users with home directories in places like /var or /run to fail because those paths aren't Btrfs-backed. KDE Linux fails to boot with Btrfs home enabled because sysuser configurations require a home directory on tmpfs, yet the option forces a Btrfs subvolume even for those state directories. Without this patch, sysusers aren't created properly, as seen in this failing pipeline: https://invent.kde.org/kde-linux/kde-linux/-/pipelines/1215866. With the patch, the system falls back to a regular directory when a Btrfs home is requested by config or flag but the target path isn't Btrfs-backed, and it throws a warning to stderr. That allows sysusers on tmpfs or other non-Btrfs state directories to be created successfully, and the pipeline passes: https://invent.kde.org/kde-linux/kde-linux/-/pipelines/1216261. This resolves the boot failure, fixes Plasma login and setup, and generally prevents breakage for any sysuser with a home on a non-Btrfs filesystem with said option set.

@silverhadch
Copy link
Copy Markdown
Contributor Author

CC: @Conan-Kudo

@Conan-Kudo
Copy link
Copy Markdown
Contributor

The commit message needs to be reformatted so that it's 70 chars for the title and the rest of the information needs to be in the commit body (wrapped at 79 chars).

@silverhadch silverhadch force-pushed the master branch 2 times, most recently from 29f0d3f to f7ccf92 Compare April 14, 2026 10:13
@silverhadch silverhadch changed the title Handle BTRFS Home configuration without hard failure Bugfix: Handle BTRFS Home configuration without hard failure Apr 14, 2026
@silverhadch silverhadch changed the title Bugfix: Handle BTRFS Home configuration without hard failure Bugfix: Critical sysuser home directory creation failure with BTRFS_SUBVOLUME_HOME=yes on non-Btrfs paths Apr 15, 2026
Comment thread src/useradd.c Outdated
Comment thread src/useradd.c Outdated
@silverhadch silverhadch force-pushed the master branch 3 times, most recently from e5d68a8 to aaa34da Compare April 15, 2026 10:35
Comment thread src/useradd.c
Comment thread man/useradd.8.xml Outdated
Comment thread src/useradd.c Outdated
Comment thread src/useradd.c Outdated
Comment thread src/useradd.c
Comment thread src/useradd.c
Comment thread man/useradd.8.xml
Comment thread src/useradd.c Outdated
Comment thread src/useradd.c Outdated
Comment thread src/useradd.c Outdated
Comment thread src/useradd.c Outdated
Comment thread src/useradd.c Outdated
Comment thread src/useradd.c Outdated
Comment thread src/useradd.c Outdated
Comment thread src/useradd.c
Comment thread src/useradd.c Outdated
Comment thread src/useradd.c Outdated
Copy link
Copy Markdown
Collaborator

@ikerexxe ikerexxe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alejandro-colomar I noticed something potentially confusing in this PR that I wanted your thoughts on. When I see if (is_btrfs(path)), I naturally expect boolean semantics where any non-zero value means "true". But here, -1 means "error" and should be handled differently than 1 (success).

This PR correctly handles it with if (is_btrfs(btrfs_check) > 0), but the function name makes this non-obvious. A future developer might write if (is_btrfs(path)) and accidentally treat errors as "is BTRFS".

Should we consider renaming to something like btrfs_check_filesystem() or get_btrfs_status()?

@silverhadch
Copy link
Copy Markdown
Contributor Author

@alejandro-colomar I noticed something potentially confusing in this PR that I wanted your thoughts on. When I see if (is_btrfs(path)), I naturally expect boolean semantics where any non-zero value means "true". But here, -1 means "error" and should be handled differently than 1 (success).

This PR correctly handles it with if (is_btrfs(btrfs_check) > 0), but the function name makes this non-obvious. A future developer might write if (is_btrfs(path)) and accidentally treat errors as "is BTRFS".

Should we consider renaming to something like btrfs_check_filesystem() or get_btrfs_status()?

btrfs_check_filesystem() sounds about right. I could rename it in this PR.

@alejandro-colomar
Copy link
Copy Markdown
Collaborator

@alejandro-colomar I noticed something potentially confusing in this PR that I wanted your thoughts on. When I see if (is_btrfs(path)), I naturally expect boolean semantics where any non-zero value means "true". But here, -1 means "error" and should be handled differently than 1 (success).

Agree. It seems confusing.

This PR correctly handles it with if (is_btrfs(btrfs_check) > 0), but the function name makes this non-obvious. A future developer might write if (is_btrfs(path)) and accidentally treat errors as "is BTRFS".

Should we consider renaming to something like btrfs_check_filesystem() or get_btrfs_status()?

I like the first suggestion.

It should return 0 if it's btrfs, and non-zero (not success) if not.

@silverhadch silverhadch force-pushed the master branch 3 times, most recently from 32303ae to be35017 Compare April 20, 2026 10:30
Comment thread man/useradd.8.xml
<replaceable>LOGIN</replaceable> name to
<replaceable>BASE_DIR</replaceable> and use that as the
login directory name.
login directory name.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the second commit:

Reviewed-by: Alejandro Colomar <alx@kernel.org>

Copy link
Copy Markdown
Collaborator

@alejandro-colomar alejandro-colomar Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was only for the second commit (now third).

Commits 1 and 2 are not reviewed. Please remove the Reviewed-by tags from them.

Comment thread lib/btrfs.c
When the --btrfs-subvolume-home option is used but the parent directory
is not on a BTRFS filesystem, useradd previously failed with an error.
This is too strict; instead, fall back to creating a regular directory
and issue a warning. The subvolume creation is attempted only when the
parent is BTRFS. Otherwise, a regular directory is created and a syslog
warning is logged.

Fixes: 3e8c105 (2026-01-02; "src/useradd: Support config for creating
    home dirs as Btrfs subvolumes")

Signed-off-by: Hadi Chokr <hadichokr@icloud.com>
Reviewed-by: Alejandro Colomar <alx@kernel.org>
The old return value (1=btrfs, 0=not, -1=err) conflated false and error.
New convention:

  0  – path is on a Btrfs filesystem
  1  – path is not on Btrfs (statfs succeeded)
 -1  – error (statfs failed)

Update prototypes.h and all call sites.

Signed-off-by: Hadi Chokr <hadichokr@icloud.com>
Reviewed-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Hadi Chokr <hadichokr@icloud.com>
Reviewed-by: Alejandro Colomar <alx@kernel.org>
Comment thread lib/btrfs.c
Comment on lines -66 to +70
ret = is_btrfs(path);
if (ret <= 0)
return ret;
ret = btrfs_check_filesystem(path);
if (ret == -1)
return -1;
if (ret != 0)
return 0;
Copy link
Copy Markdown
Collaborator

@alejandro-colomar alejandro-colomar Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer the refacctor to happen before the behavior change; that is, reorder commits 1 and 2. Would that be possible?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants