mirror of
https://github.com/hardkernel/linux.git
synced 2026-03-24 19:40:21 +09:00
shmem: fix tmpfs reconfiguration (remount) when noswap is set
commit 3cd1548a278c7d6a9bdef1f1866e7cf66bfd3518 upstream.
In systemd we're trying to switch the internal credentials setup logic
to new mount API [1], and I noticed fsconfig(FSCONFIG_CMD_RECONFIGURE)
consistently fails on tmpfs with noswap option. This can be trivially
reproduced with the following:
```
int fs_fd = fsopen("tmpfs", 0);
fsconfig(fs_fd, FSCONFIG_SET_FLAG, "noswap", NULL, 0);
fsconfig(fs_fd, FSCONFIG_CMD_CREATE, NULL, NULL, 0);
fsmount(fs_fd, 0, 0);
fsconfig(fs_fd, FSCONFIG_CMD_RECONFIGURE, NULL, NULL, 0); <------ EINVAL
```
After some digging the culprit is shmem_reconfigure() rejecting
!(ctx->seen & SHMEM_SEEN_NOSWAP) && sbinfo->noswap, which is bogus
as ctx->seen serves as a mask for whether certain options are touched
at all. On top of that, noswap option doesn't use fsparam_flag_no,
hence it's not really possible to "reenable" swap to begin with.
Drop the check and redundant SHMEM_SEEN_NOSWAP flag.
[1] https://github.com/systemd/systemd/pull/39637
Fixes: 2c6efe9cf2 ("shmem: add support to ignore swap")
Signed-off-by: Mike Yuan <me@yhndnzj.com>
Link: https://patch.msgid.link/20251108190930.440685-1-me@yhndnzj.com
Cc: Luis Chamberlain <mcgrof@kernel.org>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Hugh Dickins <hughd@google.com>
Cc: stable@vger.kernel.org
Signed-off-by: Christian Brauner <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
457376c6fb
commit
583990e7dc
15
mm/shmem.c
15
mm/shmem.c
@@ -126,8 +126,7 @@ struct shmem_options {
|
||||
#define SHMEM_SEEN_INODES 2
|
||||
#define SHMEM_SEEN_HUGE 4
|
||||
#define SHMEM_SEEN_INUMS 8
|
||||
#define SHMEM_SEEN_NOSWAP 16
|
||||
#define SHMEM_SEEN_QUOTA 32
|
||||
#define SHMEM_SEEN_QUOTA 16
|
||||
};
|
||||
|
||||
#ifdef CONFIG_TMPFS
|
||||
@@ -4004,7 +4003,6 @@ static int shmem_parse_one(struct fs_context *fc, struct fs_parameter *param)
|
||||
"Turning off swap in unprivileged tmpfs mounts unsupported");
|
||||
}
|
||||
ctx->noswap = true;
|
||||
ctx->seen |= SHMEM_SEEN_NOSWAP;
|
||||
break;
|
||||
case Opt_quota:
|
||||
if (fc->user_ns != &init_user_ns)
|
||||
@@ -4154,14 +4152,15 @@ static int shmem_reconfigure(struct fs_context *fc)
|
||||
err = "Current inum too high to switch to 32-bit inums";
|
||||
goto out;
|
||||
}
|
||||
if ((ctx->seen & SHMEM_SEEN_NOSWAP) && ctx->noswap && !sbinfo->noswap) {
|
||||
|
||||
/*
|
||||
* "noswap" doesn't use fsparam_flag_no, i.e. there's no "swap"
|
||||
* counterpart for (re-)enabling swap.
|
||||
*/
|
||||
if (ctx->noswap && !sbinfo->noswap) {
|
||||
err = "Cannot disable swap on remount";
|
||||
goto out;
|
||||
}
|
||||
if (!(ctx->seen & SHMEM_SEEN_NOSWAP) && !ctx->noswap && sbinfo->noswap) {
|
||||
err = "Cannot enable swap on remount if it was disabled on first mount";
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ctx->seen & SHMEM_SEEN_QUOTA &&
|
||||
!sb_any_quota_loaded(fc->root->d_sb)) {
|
||||
|
||||
Reference in New Issue
Block a user