We have enabled "volatile" fsync_mode on our Kubernetes production environment to prevent container exit from being blocked when there are many dirty pages to flush. This has worked well without introducing any issues. However, on some of our production servers, upgrading the container runtime to support the "volatile" mount option is not straightforward [0]. To address this, we want to enable it by default within the kernel. Add a Kconfig option to set the default fsync_mode at build time, and allow it to be overridden dynamically via a module parameter when loading overlayfs. This also aligns with how other features are configured. Link: https://github.com/containerd/containerd/issues/6406 [0] Signed-off-by: Yafang Shao --- fs/overlayfs/Kconfig | 15 +++++++++++++++ fs/overlayfs/params.c | 40 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/fs/overlayfs/Kconfig b/fs/overlayfs/Kconfig index 2ac67e04a6fb..4aeae8232c39 100644 --- a/fs/overlayfs/Kconfig +++ b/fs/overlayfs/Kconfig @@ -134,3 +134,18 @@ config OVERLAY_FS_DEBUG Say Y here to enable extra debugging checks in overlayfs. If unsure, say N. + +config OVERLAY_FS_FSYNC_MODE + int "Overlayfs: default fsync mode" + depends on OVERLAY_FS + range 0 2 + default 1 + help + Set the default fsync mode for Overlayfs. + + 0: volatile - Do not sync filesystem on fsync + 1: auto - Automatically detect sync behavior (default) + 2: strict - Always sync filesystem on fsync + + This can be overridden at runtime via the fsync_mode module + parameter or per-mount with the 'fsync=' mount option. diff --git a/fs/overlayfs/params.c b/fs/overlayfs/params.c index c93fcaa45d4a..e0c88cf19d51 100644 --- a/fs/overlayfs/params.c +++ b/fs/overlayfs/params.c @@ -153,11 +153,49 @@ static const char *ovl_fsync_mode(struct ovl_config *config) return ovl_parameter_fsync[config->fsync_mode].name; } +static int ovl_default_fsync = CONFIG_OVERLAY_FS_FSYNC_MODE; static int ovl_fsync_mode_def(void) { - return OVL_FSYNC_AUTO; + return ovl_default_fsync; } +static int ovl_fsync_mode_set(const char *val, const struct kernel_param *kp) +{ + int i; + int *p = kp->arg; + + if (!val) + return -EINVAL; + + for (i = 0; i < ARRAY_SIZE(ovl_parameter_fsync); i++) { + if (sysfs_streq(val, ovl_parameter_fsync[i].name)) { + *p = ovl_parameter_fsync[i].value; + return 0; + } + } + return -EINVAL; +} + +static int ovl_fsync_mode_get(char *buffer, const struct kernel_param *kp) +{ + int val = *(int *)kp->arg; + int i; + + for (i = 0; i < ARRAY_SIZE(ovl_parameter_fsync); i++) { + if (ovl_parameter_fsync[i].value == val) + return sysfs_emit(buffer, "%s\n", ovl_parameter_fsync[i].name); + } + return sysfs_emit(buffer, "unknown\n"); +} + +static const struct kernel_param_ops ovl_fsync_mode_ops = { + .set = ovl_fsync_mode_set, + .get = ovl_fsync_mode_get, +}; + +module_param_cb(fsync_mode, &ovl_fsync_mode_ops, &ovl_default_fsync, 0644); +MODULE_PARM_DESC(fsync_mode, "fsync mode: auto, volatile, strict (default: auto)"); + const struct fs_parameter_spec ovl_parameter_spec[] = { fsparam_string_empty("lowerdir", Opt_lowerdir), fsparam_file_or_string("lowerdir+", Opt_lowerdir_add), -- 2.52.0