[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20241106-mehrzahl-bezaubern-109237c971e3@brauner>
Date: Wed, 6 Nov 2024 10:59:12 +0100
From: Christian Brauner <brauner@...nel.org>
To: Aleksa Sarai <cyphar@...har.com>
Cc: Miklos Szeredi <miklos@...redi.hu>,
Amir Goldstein <amir73il@...il.com>, Jan Kara <jack@...e.cz>, linux-unionfs@...r.kernel.org,
linux-fs@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: Re: [PATCH] overlayfs: port all superblock creation logging to
fsopen logs
On Wed, Nov 06, 2024 at 02:09:58PM +1100, Aleksa Sarai wrote:
> overlayfs helpfully provides a lot of of information when setting up a
> mount, but unfortunately when using the fsopen(2) API, a lot of this
> information is mixed in with the general kernel log.
>
> In addition, some of the logs can become a source of spam if programs
> are creating many internal overlayfs mounts (in runc we use an internal
> overlayfs mount to protect the runc binary against container breakout
> attacks like CVE-2019-5736, and xino_auto=on caused a lot of spam in
> dmesg because we didn't explicitly disable xino[1]).
>
> By logging to the fs_context, userspace can get more accurate
> information when using fsopen(2) and there is less dmesg spam for
> systems where a lot of programs are using fsopen("overlay"). Legacy
> mount(2) users will still see the same errors in dmesg as they did
> before (though the prefix of the log messages will now be "overlay"
> rather than "overlayfs").
>
> [1]: https://bbs.archlinux.org/viewtopic.php?pid=2206551
>
> Signed-off-by: Aleksa Sarai <cyphar@...har.com>
> ---
To me this sounds inherently useful! So I'm all for it.
> In order to avoid passing fs_context everywhere, I opted to pass p_log
> instead to functions that only did some ancilliary logging and only pass
> fs_context to functions that already took ovl_fs_context. While I feel
> this makes it clearer which functions are just using fs_context for
> logging purposes, this makes overlayfs the first real user of p_log, and
> I'm not sure how you folks might feel about that.
>
> I've also tried to unify the layout of log messages (with some
> exceptions) but I guess it's possible that keeping the existing
> formatting might be important for programs that parse dmesg. Let me know
> if you'd like to keep the existing (inconsistent) formatting.
>
> Since this isn't explicitly documented, I aught to mention that the
> fc_context logs are available even after *_fill_super is completed and
> the superblock has been created, so logging info/warn messages in
> *_fill_super is still fine and userspace will still be able to get the
> logs after doing fsconfig(FSCONFIG_CREATE).
> ---
> fs/overlayfs/params.c | 151 ++++++++++++++------------------
> fs/overlayfs/params.h | 3 +-
> fs/overlayfs/super.c | 232 ++++++++++++++++++++++++++------------------------
> 3 files changed, 183 insertions(+), 203 deletions(-)
>
> diff --git a/fs/overlayfs/params.c b/fs/overlayfs/params.c
> index e42546c6c5df..d72f642df38e 100644
> --- a/fs/overlayfs/params.c
> +++ b/fs/overlayfs/params.c
> @@ -186,7 +186,7 @@ static int ovl_parse_monolithic(struct fs_context *fc, void *data)
> return vfs_parse_monolithic_sep(fc, data, ovl_next_opt);
> }
>
> -static ssize_t ovl_parse_param_split_lowerdirs(char *str)
> +static ssize_t ovl_parse_param_split_lowerdirs(struct p_log *log, char *str)
> {
> ssize_t nr_layers = 1, nr_colons = 0;
> char *s, *d;
> @@ -199,10 +199,8 @@ static ssize_t ovl_parse_param_split_lowerdirs(char *str)
> bool next_colon = (*(s + 1) == ':');
>
> nr_colons++;
> - if (nr_colons == 2 && next_colon) {
> - pr_err("only single ':' or double '::' sequences of unescaped colons in lowerdir mount option allowed.\n");
> - return -EINVAL;
> - }
> + if (nr_colons == 2 && next_colon)
> + return inval_plog(log, "only single ':' or double '::' sequences of unescaped colons in lowerdir mount option allowed");
> /* count layers, not colons */
> if (!next_colon)
> nr_layers++;
> @@ -214,10 +212,8 @@ static ssize_t ovl_parse_param_split_lowerdirs(char *str)
> *d = *s;
> if (!*s) {
> /* trailing colons */
> - if (nr_colons) {
> - pr_err("unescaped trailing colons in lowerdir mount option.\n");
> - return -EINVAL;
> - }
> + if (nr_colons)
> + return inval_plog(log, "unescaped trailing colons in lowerdir mount option");
> break;
> }
> nr_colons = 0;
> @@ -226,22 +222,17 @@ static ssize_t ovl_parse_param_split_lowerdirs(char *str)
> return nr_layers;
> }
>
> -static int ovl_mount_dir_noesc(const char *name, struct path *path)
> +static int ovl_mount_dir_noesc(struct p_log *log, const char *name,
> + struct path *path)
> {
> int err = -EINVAL;
>
> - if (!*name) {
> - pr_err("empty lowerdir\n");
> - goto out;
> - }
> - err = kern_path(name, LOOKUP_FOLLOW, path);
> - if (err) {
> - pr_err("failed to resolve '%s': %i\n", name, err);
> - goto out;
> - }
> - return 0;
> + if (!*name)
> + return inval_plog(log, "empty lowerdir");
>
> -out:
> + err = kern_path(name, LOOKUP_FOLLOW, path);
> + if (err)
> + error_plog(log, "failed to resolve '%s': %i", name, err);
> return err;
> }
>
> @@ -258,14 +249,15 @@ static void ovl_unescape(char *s)
> }
> }
>
> -static int ovl_mount_dir(const char *name, struct path *path)
> +static int ovl_mount_dir(struct p_log *log, const char *name,
> + struct path *path)
> {
> int err = -ENOMEM;
> char *tmp = kstrdup(name, GFP_KERNEL);
>
> if (tmp) {
> ovl_unescape(tmp);
> - err = ovl_mount_dir_noesc(tmp, path);
> + err = ovl_mount_dir_noesc(log, tmp, path);
> kfree(tmp);
> }
> return err;
> @@ -378,9 +370,9 @@ static int ovl_parse_layer(struct fs_context *fc, const char *layer_name, enum o
> return -ENOMEM;
>
> if (upper || layer == Opt_lowerdir)
> - err = ovl_mount_dir(name, &path);
> + err = ovl_mount_dir(&fc->log, name, &path);
> else
> - err = ovl_mount_dir_noesc(name, &path);
> + err = ovl_mount_dir_noesc(&fc->log, name, &path);
> if (err)
> goto out_free;
>
> @@ -448,10 +440,8 @@ static int ovl_parse_param_lowerdir(const char *name, struct fs_context *fc)
> if (!*name)
> return 0;
>
> - if (*name == ':') {
> - pr_err("cannot append lower layer\n");
> - return -EINVAL;
> - }
> + if (*name == ':')
> + return invalfc(fc, "cannot append lower layer");
>
> // Store user provided lowerdir string to show in mount options
> ctx->lowerdir_all = kstrdup(name, GFP_KERNEL);
> @@ -463,12 +453,12 @@ static int ovl_parse_param_lowerdir(const char *name, struct fs_context *fc)
> return -ENOMEM;
>
> err = -EINVAL;
> - nr_lower = ovl_parse_param_split_lowerdirs(dup);
> + nr_lower = ovl_parse_param_split_lowerdirs(&fc->log, dup);
> if (nr_lower < 0)
> goto out_err;
>
> if (nr_lower > OVL_MAX_STACK) {
> - pr_err("too many lower directories, limit is %d\n", OVL_MAX_STACK);
> + errorfc(fc, "too many lower directories, limit is %d", OVL_MAX_STACK);
> goto out_err;
> }
>
> @@ -493,7 +483,7 @@ static int ovl_parse_param_lowerdir(const char *name, struct fs_context *fc)
> * there are no data layers.
> */
> if (ctx->nr_data > 0) {
> - pr_err("regular lower layers cannot follow data lower layers\n");
> + errorfc(fc, "regular lower layers cannot follow data lower layers");
> goto out_err;
> }
>
> @@ -597,9 +587,8 @@ static int ovl_parse_param(struct fs_context *fc, struct fs_parameter *param)
> config->userxattr = true;
> break;
> default:
> - pr_err("unrecognized mount option \"%s\" or missing value\n",
> - param->key);
> - return -EINVAL;
> + return invalfc(fc, "unrecognized mount option \"%s\" or missing value",
> + param->key);
> }
>
> return err;
> @@ -750,44 +739,43 @@ void ovl_free_fs(struct ovl_fs *ofs)
> kfree(ofs);
> }
>
> -int ovl_fs_params_verify(const struct ovl_fs_context *ctx,
> +int ovl_fs_params_verify(struct fs_context *fc,
> struct ovl_config *config)
> {
> + const struct ovl_fs_context *ctx = fc->fs_private;
> struct ovl_opt_set set = ctx->set;
>
> /* Workdir/index are useless in non-upper mount */
> if (!config->upperdir) {
> if (config->workdir) {
> - pr_info("option \"workdir=%s\" is useless in a non-upper mount, ignore\n",
> - config->workdir);
> + infofc(fc, "option \"workdir=%s\" is useless in a non-upper mount, ignore",
> + config->workdir);
> kfree(config->workdir);
> config->workdir = NULL;
> }
> if (config->index && set.index) {
> - pr_info("option \"index=on\" is useless in a non-upper mount, ignore\n");
> + infofc(fc, "option \"index=on\" is useless in a non-upper mount, ignore");
> set.index = false;
> }
> config->index = false;
> }
>
> if (!config->upperdir && config->ovl_volatile) {
> - pr_info("option \"volatile\" is meaningless in a non-upper mount, ignoring it.\n");
> + infofc(fc, "option \"volatile\" is meaningless in a non-upper mount, ignoring it");
> config->ovl_volatile = false;
> }
>
> if (!config->upperdir && config->uuid == OVL_UUID_ON) {
> - pr_info("option \"uuid=on\" requires an upper fs, falling back to uuid=null.\n");
> + infofc(fc, "option \"uuid=on\" requires an upper fs, falling back to uuid=null");
> config->uuid = OVL_UUID_NULL;
> }
>
> /* Resolve verity -> metacopy dependency */
> if (config->verity_mode && !config->metacopy) {
> /* Don't allow explicit specified conflicting combinations */
> - if (set.metacopy) {
> - pr_err("conflicting options: metacopy=off,verity=%s\n",
> - ovl_verity_mode(config));
> - return -EINVAL;
> - }
> + if (set.metacopy)
> + return invalfc(fc, "conflicting options: metacopy=off,verity=%s",
> + ovl_verity_mode(config));
> /* Otherwise automatically enable metacopy. */
> config->metacopy = true;
> }
> @@ -801,23 +789,21 @@ int ovl_fs_params_verify(const struct ovl_fs_context *ctx,
>
> /* Resolve verity -> metacopy -> redirect_dir dependency */
> if (config->metacopy && config->redirect_mode != OVL_REDIRECT_ON) {
> - if (set.metacopy && set.redirect) {
> - pr_err("conflicting options: metacopy=on,redirect_dir=%s\n",
> - ovl_redirect_mode(config));
> - return -EINVAL;
> - }
> - if (config->verity_mode && set.redirect) {
> - pr_err("conflicting options: verity=%s,redirect_dir=%s\n",
> - ovl_verity_mode(config), ovl_redirect_mode(config));
> - return -EINVAL;
> - }
> + if (set.metacopy && set.redirect)
> + return invalfc(fc, "conflicting options: metacopy=on,redirect_dir=%s",
> + ovl_redirect_mode(config));
> + if (config->verity_mode && set.redirect)
> + return invalfc(fc, "conflicting options: verity=%s,redirect_dir=%s",
> + ovl_verity_mode(config),
> + ovl_redirect_mode(config));
> +
> if (set.redirect) {
> /*
> * There was an explicit redirect_dir=... that resulted
> * in this conflict.
> */
> - pr_info("disabling metacopy due to redirect_dir=%s\n",
> - ovl_redirect_mode(config));
> + infofc(fc, "disabling metacopy due to redirect_dir=%s",
> + ovl_redirect_mode(config));
> config->metacopy = false;
> } else {
> /* Automatically enable redirect otherwise. */
> @@ -829,17 +815,16 @@ int ovl_fs_params_verify(const struct ovl_fs_context *ctx,
> if (config->nfs_export && !config->index) {
> if (!config->upperdir &&
> config->redirect_mode != OVL_REDIRECT_NOFOLLOW) {
> - pr_info("NFS export requires \"redirect_dir=nofollow\" on non-upper mount, falling back to nfs_export=off.\n");
> + infofc(fc, "NFS export requires \"redirect_dir=nofollow\" on non-upper mount, falling back to nfs_export=off");
> config->nfs_export = false;
> } else if (set.nfs_export && set.index) {
> - pr_err("conflicting options: nfs_export=on,index=off\n");
> - return -EINVAL;
> + return invalfc(fc, "conflicting options: nfs_export=on,index=off");
> } else if (set.index) {
> /*
> * There was an explicit index=off that resulted
> * in this conflict.
> */
> - pr_info("disabling nfs_export due to index=off\n");
> + infofc(fc, "disabling nfs_export due to index=off");
> config->nfs_export = false;
> } else {
> /* Automatically enable index otherwise. */
> @@ -849,31 +834,29 @@ int ovl_fs_params_verify(const struct ovl_fs_context *ctx,
>
> /* Resolve nfs_export -> !metacopy && !verity dependency */
> if (config->nfs_export && config->metacopy) {
> - if (set.nfs_export && set.metacopy) {
> - pr_err("conflicting options: nfs_export=on,metacopy=on\n");
> - return -EINVAL;
> - }
> + if (set.nfs_export && set.metacopy)
> + return invalfc(fc, "conflicting options: nfs_export=on,metacopy=on");
> if (set.metacopy) {
> /*
> * There was an explicit metacopy=on that resulted
> * in this conflict.
> */
> - pr_info("disabling nfs_export due to metacopy=on\n");
> + infofc(fc, "disabling nfs_export due to metacopy=on");
> config->nfs_export = false;
> } else if (config->verity_mode) {
> /*
> * There was an explicit verity=.. that resulted
> * in this conflict.
> */
> - pr_info("disabling nfs_export due to verity=%s\n",
> - ovl_verity_mode(config));
> + infofc(fc, "disabling nfs_export due to verity=%s",
> + ovl_verity_mode(config));
> config->nfs_export = false;
> } else {
> /*
> * There was an explicit nfs_export=on that resulted
> * in this conflict.
> */
> - pr_info("disabling metacopy due to nfs_export=on\n");
> + infofc(fc, "disabling metacopy due to nfs_export=on");
> config->metacopy = false;
> }
> }
> @@ -882,20 +865,14 @@ int ovl_fs_params_verify(const struct ovl_fs_context *ctx,
> /* Resolve userxattr -> !redirect && !metacopy && !verity dependency */
> if (config->userxattr) {
> if (set.redirect &&
> - config->redirect_mode != OVL_REDIRECT_NOFOLLOW) {
> - pr_err("conflicting options: userxattr,redirect_dir=%s\n",
> - ovl_redirect_mode(config));
> - return -EINVAL;
> - }
> - if (config->metacopy && set.metacopy) {
> - pr_err("conflicting options: userxattr,metacopy=on\n");
> - return -EINVAL;
> - }
> - if (config->verity_mode) {
> - pr_err("conflicting options: userxattr,verity=%s\n",
> - ovl_verity_mode(config));
> - return -EINVAL;
> - }
> + config->redirect_mode != OVL_REDIRECT_NOFOLLOW)
> + return invalfc(fc, "conflicting options: userxattr,redirect_dir=%s",
> + ovl_redirect_mode(config));
> + if (config->metacopy && set.metacopy)
> + return invalfc(fc, "conflicting options: userxattr,metacopy=on");
> + if (config->verity_mode)
> + return invalfc(fc, "conflicting options: userxattr,verity=%s",
> + ovl_verity_mode(config));
> /*
> * Silently disable default setting of redirect and metacopy.
> * This shall be the default in the future as well: these
> @@ -934,10 +911,8 @@ int ovl_fs_params_verify(const struct ovl_fs_context *ctx,
> */
> }
>
> - if (ctx->nr_data > 0 && !config->metacopy) {
> - pr_err("lower data-only dirs require metacopy support.\n");
> - return -EINVAL;
> - }
> + if (ctx->nr_data > 0 && !config->metacopy)
> + return invalfc(fc, "lower data-only dirs require metacopy support");
>
> return 0;
> }
> diff --git a/fs/overlayfs/params.h b/fs/overlayfs/params.h
> index c96d93982021..0ffe64277134 100644
> --- a/fs/overlayfs/params.h
> +++ b/fs/overlayfs/params.h
> @@ -37,7 +37,6 @@ struct ovl_fs_context {
>
> int ovl_init_fs_context(struct fs_context *fc);
> void ovl_free_fs(struct ovl_fs *ofs);
> -int ovl_fs_params_verify(const struct ovl_fs_context *ctx,
> - struct ovl_config *config);
> +int ovl_fs_params_verify(struct fs_context *fc, struct ovl_config *config);
> int ovl_show_options(struct seq_file *m, struct dentry *dentry);
> const char *ovl_xino_mode(struct ovl_config *config);
> diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
> index fe511192f83c..69c6c25990ac 100644
> --- a/fs/overlayfs/super.c
> +++ b/fs/overlayfs/super.c
> @@ -272,7 +272,7 @@ static const struct super_operations ovl_super_operations = {
> #define OVL_WORKDIR_NAME "work"
> #define OVL_INDEXDIR_NAME "index"
>
> -static struct dentry *ovl_workdir_create(struct ovl_fs *ofs,
> +static struct dentry *ovl_workdir_create(struct p_log *log, struct ovl_fs *ofs,
> const char *name, bool persist)
> {
> struct inode *dir = ofs->workbasedir->d_inode;
> @@ -356,33 +356,33 @@ static struct dentry *ovl_workdir_create(struct ovl_fs *ofs,
> out_dput:
> dput(work);
> out_err:
> - pr_warn("failed to create directory %s/%s (errno: %i); mounting read-only\n",
> - ofs->config.workdir, name, -err);
> + warn_plog(log, "failed to create directory %s/%s (errno: %i); mounting read-only",
> + ofs->config.workdir, name, -err);
> work = NULL;
> goto out_unlock;
> }
>
> -static int ovl_check_namelen(const struct path *path, struct ovl_fs *ofs,
> - const char *name)
> +static int ovl_check_namelen(struct p_log *log, const struct path *path,
> + struct ovl_fs *ofs, const char *name)
> {
> struct kstatfs statfs;
> int err = vfs_statfs(path, &statfs);
>
> if (err)
> - pr_err("statfs failed on '%s'\n", name);
> + error_plog(log, "statfs failed on '%s'", name);
> else
> ofs->namelen = max(ofs->namelen, statfs.f_namelen);
>
> return err;
> }
>
> -static int ovl_lower_dir(const char *name, struct path *path,
> +static int ovl_lower_dir(struct p_log *log, const char *name, struct path *path,
> struct ovl_fs *ofs, int *stack_depth)
> {
> int fh_type;
> int err;
>
> - err = ovl_check_namelen(path, ofs, name);
> + err = ovl_check_namelen(log, path, ofs, name);
> if (err)
> return err;
>
> @@ -397,8 +397,8 @@ static int ovl_lower_dir(const char *name, struct path *path,
> (ofs->config.index && ofs->config.upperdir)) && !fh_type) {
> ofs->config.index = false;
> ofs->config.nfs_export = false;
> - pr_warn("fs on '%s' does not support file handles, falling back to index=off,nfs_export=off.\n",
> - name);
> + warn_plog(log, "fs on '%s' does not support file handles, falling back to index=off,nfs_export=off",
> + name);
> }
> ofs->nofh |= !fh_type;
> /*
> @@ -408,8 +408,8 @@ static int ovl_lower_dir(const char *name, struct path *path,
> if (ofs->config.xino == OVL_XINO_AUTO &&
> ofs->config.upperdir && !fh_type) {
> ofs->config.xino = OVL_XINO_OFF;
> - pr_warn("fs on '%s' does not support file handles, falling back to xino=off.\n",
> - name);
> + warn_plog(log, "fs on '%s' does not support file handles, falling back to xino=off",
> + name);
> }
>
> /* Check if lower fs has 32bit inode numbers */
> @@ -433,8 +433,9 @@ static bool ovl_workdir_ok(struct dentry *workdir, struct dentry *upperdir)
> return ok;
> }
>
> -static int ovl_setup_trap(struct super_block *sb, struct dentry *dir,
> - struct inode **ptrap, const char *name)
> +static int ovl_setup_trap(struct p_log *log, struct super_block *sb,
> + struct dentry *dir, struct inode **ptrap,
> + const char *name)
> {
> struct inode *trap;
> int err;
> @@ -443,7 +444,7 @@ static int ovl_setup_trap(struct super_block *sb, struct dentry *dir,
> err = PTR_ERR_OR_ZERO(trap);
> if (err) {
> if (err == -ELOOP)
> - pr_err("conflicting %s path\n", name);
> + error_plog(log, "conflicting %s path", name);
> return err;
> }
>
> @@ -457,21 +458,22 @@ static int ovl_setup_trap(struct super_block *sb, struct dentry *dir,
> * for example, an old overlay mount is leaked and now its upperdir is
> * attempted to be used as a lower layer in a new overlay mount.
> */
> -static int ovl_report_in_use(struct ovl_fs *ofs, const char *name)
> +static int ovl_report_in_use(struct p_log *log, struct ovl_fs *ofs,
> + const char *name)
> {
> if (ofs->config.index) {
> - pr_err("%s is in-use as upperdir/workdir of another mount, mount with '-o index=off' to override exclusive upperdir protection.\n",
> - name);
> + error_plog(log, "%s is in-use as upperdir/workdir of another mount, mount with '-o index=off' to override exclusive upperdir protection.",
> + name);
> return -EBUSY;
> } else {
> - pr_warn("%s is in-use as upperdir/workdir of another mount, accessing files from both mounts will result in undefined behavior.\n",
> - name);
> + warn_plog(log, "%s is in-use as upperdir/workdir of another mount, accessing files from both mounts will result in undefined behavior.",
> + name);
> return 0;
> }
> }
>
> -static int ovl_get_upper(struct super_block *sb, struct ovl_fs *ofs,
> - struct ovl_layer *upper_layer,
> +static int ovl_get_upper(struct p_log *log, struct super_block *sb,
> + struct ovl_fs *ofs, struct ovl_layer *upper_layer,
> const struct path *upperpath)
> {
> struct vfsmount *upper_mnt;
> @@ -479,16 +481,16 @@ static int ovl_get_upper(struct super_block *sb, struct ovl_fs *ofs,
>
> /* Upperdir path should not be r/o */
> if (__mnt_is_readonly(upperpath->mnt)) {
> - pr_err("upper fs is r/o, try multi-lower layers mount\n");
> + error_plog(log, "upper fs is r/o, try multi-lower layers mount");
> err = -EINVAL;
> goto out;
> }
>
> - err = ovl_check_namelen(upperpath, ofs, ofs->config.upperdir);
> + err = ovl_check_namelen(log, upperpath, ofs, ofs->config.upperdir);
> if (err)
> goto out;
>
> - err = ovl_setup_trap(sb, upperpath->dentry, &upper_layer->trap,
> + err = ovl_setup_trap(log, sb, upperpath->dentry, &upper_layer->trap,
> "upperdir");
> if (err)
> goto out;
> @@ -496,7 +498,7 @@ static int ovl_get_upper(struct super_block *sb, struct ovl_fs *ofs,
> upper_mnt = clone_private_mount(upperpath);
> err = PTR_ERR(upper_mnt);
> if (IS_ERR(upper_mnt)) {
> - pr_err("failed to clone upperpath\n");
> + error_plog(log, "failed to clone upperpath");
> goto out;
> }
>
> @@ -521,7 +523,7 @@ static int ovl_get_upper(struct super_block *sb, struct ovl_fs *ofs,
> if (ovl_inuse_trylock(ovl_upper_mnt(ofs)->mnt_root)) {
> ofs->upperdir_locked = true;
> } else {
> - err = ovl_report_in_use(ofs, "upperdir");
> + err = ovl_report_in_use(log, ofs, "upperdir");
> if (err)
> goto out;
> }
> @@ -632,8 +634,8 @@ static int ovl_create_volatile_dirty(struct ovl_fs *ofs)
> return 0;
> }
>
> -static int ovl_make_workdir(struct super_block *sb, struct ovl_fs *ofs,
> - const struct path *workpath)
> +static int ovl_make_workdir(struct p_log *log, struct super_block *sb,
> + struct ovl_fs *ofs, const struct path *workpath)
> {
> struct vfsmount *mnt = ovl_upper_mnt(ofs);
> struct dentry *workdir;
> @@ -647,14 +649,15 @@ static int ovl_make_workdir(struct super_block *sb, struct ovl_fs *ofs,
> if (err)
> return err;
>
> - workdir = ovl_workdir_create(ofs, OVL_WORKDIR_NAME, false);
> + workdir = ovl_workdir_create(log, ofs, OVL_WORKDIR_NAME, false);
> err = PTR_ERR(workdir);
> if (IS_ERR_OR_NULL(workdir))
> goto out;
>
> ofs->workdir = workdir;
>
> - err = ovl_setup_trap(sb, ofs->workdir, &ofs->workdir_trap, "workdir");
> + err = ovl_setup_trap(log, sb, ofs->workdir, &ofs->workdir_trap,
> + "workdir");
> if (err)
> goto out;
>
> @@ -670,7 +673,7 @@ static int ovl_make_workdir(struct super_block *sb, struct ovl_fs *ofs,
>
> d_type = err;
> if (!d_type)
> - pr_warn("upper fs needs to support d_type.\n");
> + warn_plog(log, "upper fs needs to support d_type");
>
> /* Check if upper/work fs supports O_TMPFILE */
> tmpfile = ovl_do_tmpfile(ofs, ofs->workdir, S_IFREG | 0);
> @@ -678,7 +681,7 @@ static int ovl_make_workdir(struct super_block *sb, struct ovl_fs *ofs,
> if (ofs->tmpfile)
> fput(tmpfile);
> else
> - pr_warn("upper fs does not support tmpfile.\n");
> + warn_plog(log, "upper fs does not support tmpfile");
>
>
> /* Check if upper/work fs supports RENAME_WHITEOUT */
> @@ -688,30 +691,30 @@ static int ovl_make_workdir(struct super_block *sb, struct ovl_fs *ofs,
>
> rename_whiteout = err;
> if (!rename_whiteout)
> - pr_warn("upper fs does not support RENAME_WHITEOUT.\n");
> + warn_plog(log, "upper fs does not support RENAME_WHITEOUT");
>
> /*
> * Check if upper/work fs supports (trusted|user).overlay.* xattr
> */
> err = ovl_setxattr(ofs, ofs->workdir, OVL_XATTR_OPAQUE, "0", 1);
> if (err) {
> - pr_warn("failed to set xattr on upper\n");
> + warn_plog(log, "failed to set xattr on upper");
> ofs->noxattr = true;
> if (ovl_redirect_follow(ofs)) {
> ofs->config.redirect_mode = OVL_REDIRECT_NOFOLLOW;
> - pr_warn("...falling back to redirect_dir=nofollow.\n");
> + warn_plog(log, "...falling back to redirect_dir=nofollow");
> }
> if (ofs->config.metacopy) {
> ofs->config.metacopy = false;
> - pr_warn("...falling back to metacopy=off.\n");
> + warn_plog(log, "...falling back to metacopy=off");
> }
> if (ofs->config.index) {
> ofs->config.index = false;
> - pr_warn("...falling back to index=off.\n");
> + warn_plog(log, "...falling back to index=off");
> }
> if (ovl_has_fsid(ofs)) {
> ofs->config.uuid = OVL_UUID_NULL;
> - pr_warn("...falling back to uuid=null.\n");
> + warn_plog(log, "...falling back to uuid=null");
> }
> /*
> * xattr support is required for persistent st_ino.
> @@ -719,10 +722,10 @@ static int ovl_make_workdir(struct super_block *sb, struct ovl_fs *ofs,
> */
> if (ofs->config.xino == OVL_XINO_AUTO) {
> ofs->config.xino = OVL_XINO_OFF;
> - pr_warn("...falling back to xino=off.\n");
> + warn_plog(log, "...falling back to xino=off");
> }
> if (err == -EPERM && !ofs->config.userxattr)
> - pr_info("try mounting with 'userxattr' option\n");
> + info_plog(log, "try mounting with 'userxattr' option");
> err = 0;
> } else {
> ovl_removexattr(ofs, ofs->workdir, OVL_XATTR_OPAQUE);
> @@ -735,7 +738,7 @@ static int ovl_make_workdir(struct super_block *sb, struct ovl_fs *ofs,
> */
> if (ovl_dentry_remote(ofs->workdir) &&
> (!d_type || !rename_whiteout || ofs->noxattr)) {
> - pr_err("upper fs missing required features.\n");
> + error_plog(log, "upper fs missing required features");
> err = -EINVAL;
> goto out;
> }
> @@ -747,7 +750,7 @@ static int ovl_make_workdir(struct super_block *sb, struct ovl_fs *ofs,
> if (ofs->config.ovl_volatile) {
> err = ovl_create_volatile_dirty(ofs);
> if (err < 0) {
> - pr_err("Failed to create volatile/dirty file.\n");
> + error_plog(log, "failed to create volatile/dirty file");
> goto out;
> }
> }
> @@ -756,7 +759,7 @@ static int ovl_make_workdir(struct super_block *sb, struct ovl_fs *ofs,
> fh_type = ovl_can_decode_fh(ofs->workdir->d_sb);
> if (ofs->config.index && !fh_type) {
> ofs->config.index = false;
> - pr_warn("upper fs does not support file handles, falling back to index=off.\n");
> + warn_plog(log, "upper fs does not support file handles, falling back to index=off");
> }
> ofs->nofh |= !fh_type;
>
> @@ -766,7 +769,7 @@ static int ovl_make_workdir(struct super_block *sb, struct ovl_fs *ofs,
>
> /* NFS export of r/w mount depends on index */
> if (ofs->config.nfs_export && !ofs->config.index) {
> - pr_warn("NFS export requires \"index=on\", falling back to nfs_export=off.\n");
> + warn_plog(log, "NFS export requires \"index=on\", falling back to nfs_export=off.");
> ofs->config.nfs_export = false;
> }
> out:
> @@ -774,42 +777,38 @@ static int ovl_make_workdir(struct super_block *sb, struct ovl_fs *ofs,
> return err;
> }
>
> -static int ovl_get_workdir(struct super_block *sb, struct ovl_fs *ofs,
> - const struct path *upperpath,
> +static int ovl_get_workdir(struct p_log *log, struct super_block *sb,
> + struct ovl_fs *ofs, const struct path *upperpath,
> const struct path *workpath)
> {
> int err;
>
> - err = -EINVAL;
> - if (upperpath->mnt != workpath->mnt) {
> - pr_err("workdir and upperdir must reside under the same mount\n");
> - return err;
> - }
> - if (!ovl_workdir_ok(workpath->dentry, upperpath->dentry)) {
> - pr_err("workdir and upperdir must be separate subtrees\n");
> - return err;
> - }
> + if (upperpath->mnt != workpath->mnt)
> + return inval_plog(log, "workdir and upperdir must reside under the same mount");
> + if (!ovl_workdir_ok(workpath->dentry, upperpath->dentry))
> + return inval_plog(log, "workdir and upperdir must be separate subtrees");
>
> ofs->workbasedir = dget(workpath->dentry);
>
> if (ovl_inuse_trylock(ofs->workbasedir)) {
> ofs->workdir_locked = true;
> } else {
> - err = ovl_report_in_use(ofs, "workdir");
> + err = ovl_report_in_use(log, ofs, "workdir");
> if (err)
> return err;
> }
>
> - err = ovl_setup_trap(sb, ofs->workbasedir, &ofs->workbasedir_trap,
> + err = ovl_setup_trap(log, sb, ofs->workbasedir, &ofs->workbasedir_trap,
> "workdir");
> if (err)
> return err;
>
> - return ovl_make_workdir(sb, ofs, workpath);
> + return ovl_make_workdir(log, sb, ofs, workpath);
> }
>
> -static int ovl_get_indexdir(struct super_block *sb, struct ovl_fs *ofs,
> - struct ovl_entry *oe, const struct path *upperpath)
> +static int ovl_get_indexdir(struct p_log *log, struct super_block *sb,
> + struct ovl_fs *ofs, struct ovl_entry *oe,
> + const struct path *upperpath)
> {
> struct vfsmount *mnt = ovl_upper_mnt(ofs);
> struct dentry *indexdir;
> @@ -828,7 +827,7 @@ static int ovl_get_indexdir(struct super_block *sb, struct ovl_fs *ofs,
> /* Verify lower root is upper root origin */
> err = ovl_verify_origin_fh(ofs, upperpath->dentry, fh, true);
> if (err) {
> - pr_err("failed to verify upper root origin\n");
> + error_plog(log, "failed to verify upper root origin");
> goto out;
> }
>
> @@ -837,12 +836,12 @@ static int ovl_get_indexdir(struct super_block *sb, struct ovl_fs *ofs,
> ofs->workdir_trap = NULL;
> dput(ofs->workdir);
> ofs->workdir = NULL;
> - indexdir = ovl_workdir_create(ofs, OVL_INDEXDIR_NAME, true);
> + indexdir = ovl_workdir_create(log, ofs, OVL_INDEXDIR_NAME, true);
> if (IS_ERR(indexdir)) {
> err = PTR_ERR(indexdir);
> } else if (indexdir) {
> ofs->workdir = indexdir;
> - err = ovl_setup_trap(sb, indexdir, &ofs->workdir_trap,
> + err = ovl_setup_trap(log, sb, indexdir, &ofs->workdir_trap,
> "indexdir");
> if (err)
> goto out;
> @@ -861,18 +860,18 @@ static int ovl_get_indexdir(struct super_block *sb, struct ovl_fs *ofs,
> upperpath->dentry, true,
> false);
> if (err)
> - pr_err("failed to verify index dir 'origin' xattr\n");
> + error_plog(log, "failed to verify index dir 'origin' xattr");
> }
> err = ovl_verify_upper(ofs, indexdir, upperpath->dentry, true);
> if (err)
> - pr_err("failed to verify index dir 'upper' xattr\n");
> + error_plog(log, "failed to verify index dir 'upper' xattr");
>
> /* Cleanup bad/stale/orphan index entries */
> if (!err)
> err = ovl_indexdir_cleanup(ofs);
> }
> if (err || !indexdir)
> - pr_warn("try deleting index dir or mounting with '-o index=off' to disable inodes index.\n");
> + error_plog(log, "try deleting index dir or mounting with '-o index=off' to disable inodes index");
>
> out:
> mnt_drop_write(mnt);
> @@ -917,7 +916,8 @@ static bool ovl_lower_uuid_ok(struct ovl_fs *ofs, const uuid_t *uuid)
> }
>
> /* Get a unique fsid for the layer */
> -static int ovl_get_fsid(struct ovl_fs *ofs, const struct path *path)
> +static int ovl_get_fsid(struct p_log *log, struct ovl_fs *ofs,
> + const struct path *path)
> {
> struct super_block *sb = path->mnt->mnt_sb;
> unsigned int i;
> @@ -943,16 +943,17 @@ static int ovl_get_fsid(struct ovl_fs *ofs, const struct path *path)
> warn = true;
> }
> if (warn) {
> - pr_warn("%s uuid detected in lower fs '%pd2', falling back to xino=%s,index=off,nfs_export=off.\n",
> - uuid_is_null(&sb->s_uuid) ? "null" :
> - "conflicting",
> - path->dentry, ovl_xino_mode(&ofs->config));
> + warn_plog(log,
> + "%s uuid detected in lower fs '%pd2', falling back to xino=%s,index=off,nfs_export=off",
> + uuid_is_null(&sb->s_uuid) ? "null" :
> + "conflicting",
> + path->dentry, ovl_xino_mode(&ofs->config));
> }
> }
>
> err = get_anon_bdev(&dev);
> if (err) {
> - pr_err("failed to get anonymous bdev for lowerpath\n");
> + error_plog(log, "failed to get anonymous bdev for lowerpath");
> return err;
> }
>
> @@ -974,11 +975,12 @@ static int ovl_get_data_fsid(struct ovl_fs *ofs)
>
>
> static int ovl_get_layers(struct super_block *sb, struct ovl_fs *ofs,
> - struct ovl_fs_context *ctx, struct ovl_layer *layers)
> + struct fs_context *fc, struct ovl_layer *layers)
> {
> int err;
> unsigned int i;
> size_t nr_merged_lower;
> + struct ovl_fs_context *ctx = fc->fs_private;
>
> ofs->fs = kcalloc(ctx->nr + 2, sizeof(struct ovl_sb), GFP_KERNEL);
> if (ofs->fs == NULL)
> @@ -998,7 +1000,7 @@ static int ovl_get_layers(struct super_block *sb, struct ovl_fs *ofs,
> */
> err = get_anon_bdev(&ofs->fs[0].pseudo_dev);
> if (err) {
> - pr_err("failed to get anonymous bdev for upper fs\n");
> + errorfc(fc, "failed to get anonymous bdev for upper fs");
> return err;
> }
>
> @@ -1015,7 +1017,7 @@ static int ovl_get_layers(struct super_block *sb, struct ovl_fs *ofs,
> int fsid;
>
> if (i < nr_merged_lower)
> - fsid = ovl_get_fsid(ofs, &l->path);
> + fsid = ovl_get_fsid(&fc->log, ofs, &l->path);
> else
> fsid = ovl_get_data_fsid(ofs);
> if (fsid < 0)
> @@ -1028,12 +1030,13 @@ static int ovl_get_layers(struct super_block *sb, struct ovl_fs *ofs,
> * the upperdir/workdir is in fact in-use by our
> * upperdir/workdir.
> */
> - err = ovl_setup_trap(sb, l->path.dentry, &trap, "lowerdir");
> + err = ovl_setup_trap(&fc->log, sb, l->path.dentry, &trap,
> + "lowerdir");
> if (err)
> return err;
>
> if (ovl_is_inuse(l->path.dentry)) {
> - err = ovl_report_in_use(ofs, "lowerdir");
> + err = ovl_report_in_use(&fc->log, ofs, "lowerdir");
> if (err) {
> iput(trap);
> return err;
> @@ -1043,7 +1046,7 @@ static int ovl_get_layers(struct super_block *sb, struct ovl_fs *ofs,
> mnt = clone_private_mount(&l->path);
> err = PTR_ERR(mnt);
> if (IS_ERR(mnt)) {
> - pr_err("failed to clone lowerpath\n");
> + errorfc(fc, "failed to clone lowerpath");
> iput(trap);
> return err;
> }
> @@ -1077,7 +1080,7 @@ static int ovl_get_layers(struct super_block *sb, struct ovl_fs *ofs,
> */
> if (ofs->numfs - !ovl_upper_mnt(ofs) == 1) {
> if (ofs->config.xino == OVL_XINO_ON)
> - pr_info("\"xino=on\" is useless with all layers on same fs, ignore.\n");
> + infofc(fc, "\"xino=on\" is useless with all layers on same fs, ignore");
> ofs->xino_mode = 0;
> } else if (ofs->config.xino == OVL_XINO_OFF) {
> ofs->xino_mode = -1;
> @@ -1094,15 +1097,15 @@ static int ovl_get_layers(struct super_block *sb, struct ovl_fs *ofs,
> }
>
> if (ofs->xino_mode > 0) {
> - pr_info("\"xino\" feature enabled using %d upper inode bits.\n",
> - ofs->xino_mode);
> + infofc(fc, "\"xino\" feature enabled using %d upper inode bits",
> + ofs->xino_mode);
> }
>
> return 0;
> }
>
> static struct ovl_entry *ovl_get_lowerstack(struct super_block *sb,
> - struct ovl_fs_context *ctx,
> + struct fs_context *fc,
> struct ovl_fs *ofs,
> struct ovl_layer *layers)
> {
> @@ -1111,19 +1114,19 @@ static struct ovl_entry *ovl_get_lowerstack(struct super_block *sb,
> size_t nr_merged_lower;
> struct ovl_entry *oe;
> struct ovl_path *lowerstack;
> + struct ovl_fs_context *ctx = fc->fs_private;
>
> struct ovl_fs_context_layer *l;
>
> - if (!ofs->config.upperdir && ctx->nr == 1) {
> - pr_err("at least 2 lowerdir are needed while upperdir nonexistent\n");
> - return ERR_PTR(-EINVAL);
> - }
> + if (!ofs->config.upperdir && ctx->nr == 1)
> + return ERR_PTR(invalfc(fc, "at least 2 lowerdir are needed while upperdir nonexistent"));
>
> err = -EINVAL;
> for (i = 0; i < ctx->nr; i++) {
> l = &ctx->lower[i];
>
> - err = ovl_lower_dir(l->name, &l->path, ofs, &sb->s_stack_depth);
> + err = ovl_lower_dir(&fc->log, l->name, &l->path, ofs,
> + &sb->s_stack_depth);
> if (err)
> return ERR_PTR(err);
> }
> @@ -1131,11 +1134,11 @@ static struct ovl_entry *ovl_get_lowerstack(struct super_block *sb,
> err = -EINVAL;
> sb->s_stack_depth++;
> if (sb->s_stack_depth > FILESYSTEM_MAX_STACK_DEPTH) {
> - pr_err("maximum fs stacking depth exceeded\n");
> + errorfc(fc, "maximum fs stacking depth exceeded");
> return ERR_PTR(err);
> }
>
> - err = ovl_get_layers(sb, ofs, ctx, layers);
> + err = ovl_get_layers(sb, ofs, fc, layers);
> if (err)
> return ERR_PTR(err);
>
> @@ -1162,9 +1165,9 @@ static struct ovl_entry *ovl_get_lowerstack(struct super_block *sb,
> * - another layer of this overlayfs instance
> * - upper/work dir of any overlayfs instance
> */
> -static int ovl_check_layer(struct super_block *sb, struct ovl_fs *ofs,
> - struct dentry *dentry, const char *name,
> - bool is_lower)
> +static int ovl_check_layer(struct p_log *log, struct super_block *sb,
> + struct ovl_fs *ofs, struct dentry *dentry,
> + const char *name, bool is_lower)
> {
> struct dentry *next = dentry, *parent;
> int err = 0;
> @@ -1178,9 +1181,9 @@ static int ovl_check_layer(struct super_block *sb, struct ovl_fs *ofs,
> while (!err && parent != next) {
> if (is_lower && ovl_lookup_trap_inode(sb, parent)) {
> err = -ELOOP;
> - pr_err("overlapping %s path\n", name);
> + error_plog(log, "overlapping %s path", name);
> } else if (ovl_is_inuse(parent)) {
> - err = ovl_report_in_use(ofs, name);
> + err = ovl_report_in_use(log, ofs, name);
> }
> next = parent;
> parent = dget_parent(next);
> @@ -1195,13 +1198,15 @@ static int ovl_check_layer(struct super_block *sb, struct ovl_fs *ofs,
> /*
> * Check if any of the layers or work dirs overlap.
> */
> -static int ovl_check_overlapping_layers(struct super_block *sb,
> +static int ovl_check_overlapping_layers(struct p_log *log,
> + struct super_block *sb,
> struct ovl_fs *ofs)
> {
> int i, err;
>
> if (ovl_upper_mnt(ofs)) {
> - err = ovl_check_layer(sb, ofs, ovl_upper_mnt(ofs)->mnt_root,
> + err = ovl_check_layer(log, sb, ofs,
> + ovl_upper_mnt(ofs)->mnt_root,
> "upperdir", false);
> if (err)
> return err;
> @@ -1213,14 +1218,14 @@ static int ovl_check_overlapping_layers(struct super_block *sb,
> * workbasedir. In that case, we already have their traps in
> * inode cache and we will catch that case on lookup.
> */
> - err = ovl_check_layer(sb, ofs, ofs->workbasedir, "workdir",
> - false);
> + err = ovl_check_layer(log, sb, ofs, ofs->workbasedir,
> + "workdir", false);
> if (err)
> return err;
> }
>
> for (i = 1; i < ofs->numlayer; i++) {
> - err = ovl_check_layer(sb, ofs,
> + err = ovl_check_layer(log, sb, ofs,
> ofs->layers[i].mnt->mnt_root,
> "lowerdir", true);
> if (err)
> @@ -1304,14 +1309,14 @@ int ovl_fill_super(struct super_block *sb, struct fs_context *fc)
> if (!cred)
> goto out_err;
>
> - err = ovl_fs_params_verify(ctx, &ofs->config);
> + err = ovl_fs_params_verify(fc, &ofs->config);
> if (err)
> goto out_err;
>
> err = -EINVAL;
> if (ctx->nr == 0) {
> if (!(fc->sb_flags & SB_SILENT))
> - pr_err("missing 'lowerdir'\n");
> + errorfc(fc, "missing 'lowerdir'");
> goto out_err;
> }
>
> @@ -1342,7 +1347,7 @@ int ovl_fill_super(struct super_block *sb, struct fs_context *fc)
> if (ofs->config.xino != OVL_XINO_OFF) {
> ofs->xino_mode = BITS_PER_LONG - 32;
> if (!ofs->xino_mode) {
> - pr_warn("xino not supported on 32bit kernel, falling back to xino=off.\n");
> + warnfc(fc, "xino not supported on 32bit kernel, falling back to xino=off");
> ofs->config.xino = OVL_XINO_OFF;
> }
> }
> @@ -1355,11 +1360,11 @@ int ovl_fill_super(struct super_block *sb, struct fs_context *fc)
>
> err = -EINVAL;
> if (!ofs->config.workdir) {
> - pr_err("missing 'workdir'\n");
> + errorfc(fc, "missing 'workdir'");
> goto out_err;
> }
>
> - err = ovl_get_upper(sb, ofs, &layers[0], &ctx->upper);
> + err = ovl_get_upper(&fc->log, sb, ofs, &layers[0], &ctx->upper);
> if (err)
> goto out_err;
>
> @@ -1368,12 +1373,13 @@ int ovl_fill_super(struct super_block *sb, struct fs_context *fc)
> ofs->errseq = errseq_sample(&upper_sb->s_wb_err);
> if (errseq_check(&upper_sb->s_wb_err, ofs->errseq)) {
> err = -EIO;
> - pr_err("Cannot mount volatile when upperdir has an unseen error. Sync upperdir fs to clear state.\n");
> + errorfc(fc, "Cannot mount volatile when upperdir has an unseen error. Sync upperdir fs to clear state.");
> goto out_err;
> }
> }
>
> - err = ovl_get_workdir(sb, ofs, &ctx->upper, &ctx->work);
> + err = ovl_get_workdir(&fc->log, sb, ofs,
> + &ctx->upper, &ctx->work);
> if (err)
> goto out_err;
>
> @@ -1383,7 +1389,7 @@ int ovl_fill_super(struct super_block *sb, struct fs_context *fc)
> sb->s_stack_depth = upper_sb->s_stack_depth;
> sb->s_time_gran = upper_sb->s_time_gran;
> }
> - oe = ovl_get_lowerstack(sb, ctx, ofs, layers);
> + oe = ovl_get_lowerstack(sb, fc, ofs, layers);
> err = PTR_ERR(oe);
> if (IS_ERR(oe))
> goto out_err;
> @@ -1393,7 +1399,7 @@ int ovl_fill_super(struct super_block *sb, struct fs_context *fc)
> sb->s_flags |= SB_RDONLY;
>
> if (!ovl_origin_uuid(ofs) && ofs->numfs > 1) {
> - pr_warn("The uuid=off requires a single fs for lower and upper, falling back to uuid=null.\n");
> + warnfc(fc, "The uuid=off requires a single fs for lower and upper, falling back to uuid=null.");
> ofs->config.uuid = OVL_UUID_NULL;
> } else if (ovl_has_fsid(ofs) && ovl_upper_mnt(ofs)) {
> /* Use per instance persistent uuid/fsid */
> @@ -1401,7 +1407,7 @@ int ovl_fill_super(struct super_block *sb, struct fs_context *fc)
> }
>
> if (!ovl_force_readonly(ofs) && ofs->config.index) {
> - err = ovl_get_indexdir(sb, ofs, oe, &ctx->upper);
> + err = ovl_get_indexdir(&fc->log, sb, ofs, oe, &ctx->upper);
> if (err)
> goto out_free_oe;
>
> @@ -1410,7 +1416,7 @@ int ovl_fill_super(struct super_block *sb, struct fs_context *fc)
> sb->s_flags |= SB_RDONLY;
> }
>
> - err = ovl_check_overlapping_layers(sb, ofs);
> + err = ovl_check_overlapping_layers(&fc->log, sb, ofs);
> if (err)
> goto out_free_oe;
>
> @@ -1418,13 +1424,13 @@ int ovl_fill_super(struct super_block *sb, struct fs_context *fc)
> if (!ofs->workdir) {
> ofs->config.index = false;
> if (ovl_upper_mnt(ofs) && ofs->config.nfs_export) {
> - pr_warn("NFS export requires an index dir, falling back to nfs_export=off.\n");
> + warnfc(fc, "NFS export requires an index dir, falling back to nfs_export=off.");
> ofs->config.nfs_export = false;
> }
> }
>
> if (ofs->config.metacopy && ofs->config.nfs_export) {
> - pr_warn("NFS export is not supported with metadata only copy up, falling back to nfs_export=off.\n");
> + warnfc(fc, "NFS export is not supported with metadata only copy up, falling back to nfs_export=off.");
> ofs->config.nfs_export = false;
> }
>
>
> ---
> base-commit: 59b723cd2adbac2a34fc8e12c74ae26ae45bf230
> change-id: 20241106-overlayfs-fsopen-log-e64f175203ba
>
> Best regards,
> --
> Aleksa Sarai <cyphar@...har.com>
>
Powered by blists - more mailing lists