lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<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

Powered by Openwall GNU/*/Linux Powered by OpenVZ