Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /* Provide a way to create a superblock configuration context within the kernel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * that allows a superblock to be set up prior to mounting.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (C) 2017 Red Hat, Inc. All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * Written by David Howells (dhowells@redhat.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/fs_context.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/fs_parser.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/mount.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/nsproxy.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/magic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/security.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/mnt_namespace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/pid_namespace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <linux/user_namespace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <net/net_namespace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <asm/sections.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include "mount.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include "internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) enum legacy_fs_param {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	LEGACY_FS_UNSET_PARAMS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	LEGACY_FS_MONOLITHIC_PARAMS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	LEGACY_FS_INDIVIDUAL_PARAMS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) struct legacy_fs_context {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	char			*legacy_data;	/* Data page for legacy filesystems */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	size_t			data_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	enum legacy_fs_param	param_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) static int legacy_init_fs_context(struct fs_context *fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) static const struct constant_table common_set_sb_flag[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	{ "dirsync",	SB_DIRSYNC },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	{ "lazytime",	SB_LAZYTIME },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	{ "mand",	SB_MANDLOCK },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	{ "ro",		SB_RDONLY },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	{ "sync",	SB_SYNCHRONOUS },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	{ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) static const struct constant_table common_clear_sb_flag[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	{ "async",	SB_SYNCHRONOUS },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	{ "nolazytime",	SB_LAZYTIME },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	{ "nomand",	SB_MANDLOCK },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	{ "rw",		SB_RDONLY },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	{ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59)  * Check for a common mount option that manipulates s_flags.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) static int vfs_parse_sb_flag(struct fs_context *fc, const char *key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	unsigned int token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	token = lookup_constant(common_set_sb_flag, key, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	if (token) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 		fc->sb_flags |= token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 		fc->sb_flags_mask |= token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	token = lookup_constant(common_clear_sb_flag, key, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	if (token) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 		fc->sb_flags &= ~token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 		fc->sb_flags_mask |= token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	return -ENOPARAM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83)  * vfs_parse_fs_param - Add a single parameter to a superblock config
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84)  * @fc: The filesystem context to modify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85)  * @param: The parameter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87)  * A single mount option in string form is applied to the filesystem context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88)  * being set up.  Certain standard options (for example "ro") are translated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89)  * into flag bits without going to the filesystem.  The active security module
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90)  * is allowed to observe and poach options.  Any other options are passed over
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91)  * to the filesystem to parse.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93)  * This may be called multiple times for a context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95)  * Returns 0 on success and a negative error code on failure.  In the event of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96)  * failure, supplementary error information may have been set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) int vfs_parse_fs_param(struct fs_context *fc, struct fs_parameter *param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	if (!param->key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		return invalf(fc, "Unnamed parameter\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	ret = vfs_parse_sb_flag(fc, param->key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	if (ret != -ENOPARAM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	ret = security_fs_context_parse_param(fc, param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	if (ret != -ENOPARAM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 		/* Param belongs to the LSM or is disallowed by the LSM; so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 		 * don't pass to the FS.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	if (fc->ops->parse_param) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		ret = fc->ops->parse_param(fc, param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 		if (ret != -ENOPARAM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	/* If the filesystem doesn't take any arguments, give it the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	 * default handling of source.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	if (strcmp(param->key, "source") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 		if (param->type != fs_value_is_string)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 			return invalf(fc, "VFS: Non-string source");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 		if (fc->source)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 			return invalf(fc, "VFS: Multiple sources");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 		fc->source = param->string;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 		param->string = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	return invalf(fc, "%s: Unknown parameter '%s'",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 		      fc->fs_type->name, param->key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) EXPORT_SYMBOL(vfs_parse_fs_param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)  * vfs_parse_fs_string - Convenience function to just parse a string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) int vfs_parse_fs_string(struct fs_context *fc, const char *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 			const char *value, size_t v_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	struct fs_parameter param = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 		.key	= key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 		.type	= fs_value_is_flag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 		.size	= v_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	if (value) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 		param.string = kmemdup_nul(value, v_size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		if (!param.string)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 		param.type = fs_value_is_string;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	ret = vfs_parse_fs_param(fc, &param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	kfree(param.string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) EXPORT_SYMBOL(vfs_parse_fs_string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)  * generic_parse_monolithic - Parse key[=val][,key[=val]]* mount data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)  * @ctx: The superblock configuration to fill in.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)  * @data: The data to parse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)  * Parse a blob of data that's in key[=val][,key[=val]]* form.  This can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)  * called from the ->monolithic_mount_data() fs_context operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)  * Returns 0 on success or the error returned by the ->parse_option() fs_context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)  * operation on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) int generic_parse_monolithic(struct fs_context *fc, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	char *options = data, *key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	if (!options)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	ret = security_sb_eat_lsm_opts(options, &fc->security);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	while ((key = strsep(&options, ",")) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 		if (*key) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 			size_t v_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 			char *value = strchr(key, '=');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 			if (value) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 				if (value == key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 					continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 				*value++ = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 				v_len = strlen(value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 			ret = vfs_parse_fs_string(fc, key, value, v_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 			if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) EXPORT_SYMBOL(generic_parse_monolithic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)  * alloc_fs_context - Create a filesystem context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)  * @fs_type: The filesystem type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)  * @reference: The dentry from which this one derives (or NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)  * @sb_flags: Filesystem/superblock flags (SB_*)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)  * @sb_flags_mask: Applicable members of @sb_flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)  * @purpose: The purpose that this configuration shall be used for.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)  * Open a filesystem and create a mount context.  The mount context is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)  * initialised with the supplied flags and, if a submount/automount from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)  * another superblock (referred to by @reference) is supplied, may have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)  * parameters such as namespaces copied across from that superblock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) static struct fs_context *alloc_fs_context(struct file_system_type *fs_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 				      struct dentry *reference,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 				      unsigned int sb_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 				      unsigned int sb_flags_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 				      enum fs_context_purpose purpose)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	int (*init_fs_context)(struct fs_context *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	struct fs_context *fc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	int ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	fc = kzalloc(sizeof(struct fs_context), GFP_KERNEL_ACCOUNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	if (!fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 		return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	fc->purpose	= purpose;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	fc->sb_flags	= sb_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	fc->sb_flags_mask = sb_flags_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	fc->fs_type	= get_filesystem(fs_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	fc->cred	= get_current_cred();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	fc->net_ns	= get_net(current->nsproxy->net_ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	fc->log.prefix	= fs_type->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	mutex_init(&fc->uapi_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	switch (purpose) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	case FS_CONTEXT_FOR_MOUNT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 		fc->user_ns = get_user_ns(fc->cred->user_ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	case FS_CONTEXT_FOR_SUBMOUNT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 		fc->user_ns = get_user_ns(reference->d_sb->s_user_ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	case FS_CONTEXT_FOR_RECONFIGURE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 		atomic_inc(&reference->d_sb->s_active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 		fc->user_ns = get_user_ns(reference->d_sb->s_user_ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		fc->root = dget(reference);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	/* TODO: Make all filesystems support this unconditionally */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	init_fs_context = fc->fs_type->init_fs_context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	if (!init_fs_context)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 		init_fs_context = legacy_init_fs_context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	ret = init_fs_context(fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 		goto err_fc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	fc->need_free = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	return fc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) err_fc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	put_fs_context(fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	return ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) struct fs_context *fs_context_for_mount(struct file_system_type *fs_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 					unsigned int sb_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	return alloc_fs_context(fs_type, NULL, sb_flags, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 					FS_CONTEXT_FOR_MOUNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) EXPORT_SYMBOL(fs_context_for_mount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) struct fs_context *fs_context_for_reconfigure(struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 					unsigned int sb_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 					unsigned int sb_flags_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	return alloc_fs_context(dentry->d_sb->s_type, dentry, sb_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 				sb_flags_mask, FS_CONTEXT_FOR_RECONFIGURE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) EXPORT_SYMBOL(fs_context_for_reconfigure);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) struct fs_context *fs_context_for_submount(struct file_system_type *type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 					   struct dentry *reference)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	return alloc_fs_context(type, reference, 0, 0, FS_CONTEXT_FOR_SUBMOUNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) EXPORT_SYMBOL(fs_context_for_submount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) void fc_drop_locked(struct fs_context *fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	struct super_block *sb = fc->root->d_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	dput(fc->root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	fc->root = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	deactivate_locked_super(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) static void legacy_fs_context_free(struct fs_context *fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)  * vfs_dup_fc_config: Duplicate a filesystem context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)  * @src_fc: The context to copy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) struct fs_context *vfs_dup_fs_context(struct fs_context *src_fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	struct fs_context *fc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	if (!src_fc->ops->dup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 		return ERR_PTR(-EOPNOTSUPP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	fc = kmemdup(src_fc, sizeof(struct fs_context), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	if (!fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 		return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	mutex_init(&fc->uapi_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	fc->fs_private	= NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	fc->s_fs_info	= NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	fc->source	= NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	fc->security	= NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	get_filesystem(fc->fs_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	get_net(fc->net_ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	get_user_ns(fc->user_ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	get_cred(fc->cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	if (fc->log.log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 		refcount_inc(&fc->log.log->usage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	/* Can't call put until we've called ->dup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	ret = fc->ops->dup(fc, src_fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 		goto err_fc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	ret = security_fs_context_dup(fc, src_fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 		goto err_fc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	return fc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) err_fc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	put_fs_context(fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	return ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) EXPORT_SYMBOL(vfs_dup_fs_context);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)  * logfc - Log a message to a filesystem context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)  * @fc: The filesystem context to log to.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)  * @fmt: The format of the buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) void logfc(struct fc_log *log, const char *prefix, char level, const char *fmt, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	va_list va;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	struct va_format vaf = {.fmt = fmt, .va = &va};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	va_start(va, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	if (!log) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 		switch (level) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 		case 'w':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 			printk(KERN_WARNING "%s%s%pV\n", prefix ? prefix : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 						prefix ? ": " : "", &vaf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 		case 'e':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 			printk(KERN_ERR "%s%s%pV\n", prefix ? prefix : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 						prefix ? ": " : "", &vaf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 			printk(KERN_NOTICE "%s%s%pV\n", prefix ? prefix : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 						prefix ? ": " : "", &vaf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 		unsigned int logsize = ARRAY_SIZE(log->buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 		u8 index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 		char *q = kasprintf(GFP_KERNEL, "%c %s%s%pV\n", level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 						prefix ? prefix : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 						prefix ? ": " : "", &vaf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 		index = log->head & (logsize - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 		BUILD_BUG_ON(sizeof(log->head) != sizeof(u8) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 			     sizeof(log->tail) != sizeof(u8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 		if ((u8)(log->head - log->tail) == logsize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 			/* The buffer is full, discard the oldest message */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 			if (log->need_free & (1 << index))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 				kfree(log->buffer[index]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 			log->tail++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 		log->buffer[index] = q ? q : "OOM: Can't store error string";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 		if (q)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 			log->need_free |= 1 << index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 			log->need_free &= ~(1 << index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 		log->head++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	va_end(va);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) EXPORT_SYMBOL(logfc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)  * Free a logging structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) static void put_fc_log(struct fs_context *fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 	struct fc_log *log = fc->log.log;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 	if (log) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 		if (refcount_dec_and_test(&log->usage)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 			fc->log.log = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 			for (i = 0; i <= 7; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 				if (log->need_free & (1 << i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 					kfree(log->buffer[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 			kfree(log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)  * put_fs_context - Dispose of a superblock configuration context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)  * @fc: The context to dispose of.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) void put_fs_context(struct fs_context *fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 	struct super_block *sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	if (fc->root) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 		sb = fc->root->d_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 		dput(fc->root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 		fc->root = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 		deactivate_super(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 	if (fc->need_free && fc->ops && fc->ops->free)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 		fc->ops->free(fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	security_free_mnt_opts(&fc->security);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	put_net(fc->net_ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 	put_user_ns(fc->user_ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	put_cred(fc->cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 	put_fc_log(fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	put_filesystem(fc->fs_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 	kfree(fc->source);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 	kfree(fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) EXPORT_SYMBOL(put_fs_context);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)  * Free the config for a filesystem that doesn't support fs_context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) static void legacy_fs_context_free(struct fs_context *fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	struct legacy_fs_context *ctx = fc->fs_private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 	if (ctx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 		if (ctx->param_type == LEGACY_FS_INDIVIDUAL_PARAMS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 			kfree(ctx->legacy_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 		kfree(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)  * Duplicate a legacy config.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) static int legacy_fs_context_dup(struct fs_context *fc, struct fs_context *src_fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 	struct legacy_fs_context *ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 	struct legacy_fs_context *src_ctx = src_fc->fs_private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 	ctx = kmemdup(src_ctx, sizeof(*src_ctx), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	if (!ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 	if (ctx->param_type == LEGACY_FS_INDIVIDUAL_PARAMS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 		ctx->legacy_data = kmemdup(src_ctx->legacy_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 					   src_ctx->data_size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 		if (!ctx->legacy_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 			kfree(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 	fc->fs_private = ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)  * Add a parameter to a legacy config.  We build up a comma-separated list of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)  * options.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) static int legacy_parse_param(struct fs_context *fc, struct fs_parameter *param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	struct legacy_fs_context *ctx = fc->fs_private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	unsigned int size = ctx->data_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 	size_t len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 	if (strcmp(param->key, "source") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 		if (param->type != fs_value_is_string)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 			return invalf(fc, "VFS: Legacy: Non-string source");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 		if (fc->source)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 			return invalf(fc, "VFS: Legacy: Multiple sources");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 		fc->source = param->string;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 		param->string = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 	if (ctx->param_type == LEGACY_FS_MONOLITHIC_PARAMS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 		return invalf(fc, "VFS: Legacy: Can't mix monolithic and individual options");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 	switch (param->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 	case fs_value_is_string:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 		len = 1 + param->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 	case fs_value_is_flag:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 		len += strlen(param->key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 		return invalf(fc, "VFS: Legacy: Parameter type for '%s' not supported",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 			      param->key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 	if (size + len + 2 > PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 		return invalf(fc, "VFS: Legacy: Cumulative options too large");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 	if (strchr(param->key, ',') ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 	    (param->type == fs_value_is_string &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 	     memchr(param->string, ',', param->size)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 		return invalf(fc, "VFS: Legacy: Option '%s' contained comma",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 			      param->key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 	if (!ctx->legacy_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 		ctx->legacy_data = kmalloc(PAGE_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 		if (!ctx->legacy_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 	ctx->legacy_data[size++] = ',';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 	len = strlen(param->key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 	memcpy(ctx->legacy_data + size, param->key, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 	size += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 	if (param->type == fs_value_is_string) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 		ctx->legacy_data[size++] = '=';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 		memcpy(ctx->legacy_data + size, param->string, param->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 		size += param->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 	ctx->legacy_data[size] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 	ctx->data_size = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 	ctx->param_type = LEGACY_FS_INDIVIDUAL_PARAMS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)  * Add monolithic mount data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) static int legacy_parse_monolithic(struct fs_context *fc, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 	struct legacy_fs_context *ctx = fc->fs_private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 	if (ctx->param_type != LEGACY_FS_UNSET_PARAMS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 		pr_warn("VFS: Can't mix monolithic and individual options\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 	ctx->legacy_data = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 	ctx->param_type = LEGACY_FS_MONOLITHIC_PARAMS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 	if (!ctx->legacy_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 	if (fc->fs_type->fs_flags & FS_BINARY_MOUNTDATA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 	return security_sb_eat_lsm_opts(ctx->legacy_data, &fc->security);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)  * Get a mountable root with the legacy mount command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) static int legacy_get_tree(struct fs_context *fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 	struct legacy_fs_context *ctx = fc->fs_private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 	struct super_block *sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	struct dentry *root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 	root = fc->fs_type->mount(fc->fs_type, fc->sb_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 				      fc->source, ctx->legacy_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 	if (IS_ERR(root))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 		return PTR_ERR(root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 	sb = root->d_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 	BUG_ON(!sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 	fc->root = root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)  * Handle remount.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) static int legacy_reconfigure(struct fs_context *fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 	struct legacy_fs_context *ctx = fc->fs_private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 	struct super_block *sb = fc->root->d_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 	if (!sb->s_op->remount_fs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 	return sb->s_op->remount_fs(sb, &fc->sb_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 				    ctx ? ctx->legacy_data : NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) const struct fs_context_operations legacy_fs_context_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 	.free			= legacy_fs_context_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 	.dup			= legacy_fs_context_dup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 	.parse_param		= legacy_parse_param,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 	.parse_monolithic	= legacy_parse_monolithic,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 	.get_tree		= legacy_get_tree,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 	.reconfigure		= legacy_reconfigure,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)  * Initialise a legacy context for a filesystem that doesn't support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)  * fs_context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) static int legacy_init_fs_context(struct fs_context *fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 	fc->fs_private = kzalloc(sizeof(struct legacy_fs_context), GFP_KERNEL_ACCOUNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 	if (!fc->fs_private)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 	fc->ops = &legacy_fs_context_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) int parse_monolithic_mount_data(struct fs_context *fc, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 	int (*monolithic_mount_data)(struct fs_context *, void *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 	monolithic_mount_data = fc->ops->parse_monolithic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 	if (!monolithic_mount_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 		monolithic_mount_data = generic_parse_monolithic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 	return monolithic_mount_data(fc, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)  * Clean up a context after performing an action on it and put it into a state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)  * from where it can be used to reconfigure a superblock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)  * Note that here we do only the parts that can't fail; the rest is in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)  * finish_clean_context() below and in between those fs_context is marked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)  * FS_CONTEXT_AWAITING_RECONF.  The reason for splitup is that after
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)  * successful mount or remount we need to report success to userland.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)  * Trying to do full reinit (for the sake of possible subsequent remount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)  * and failing to allocate memory would've put us into a nasty situation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)  * So here we only discard the old state and reinitialization is left
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)  * until we actually try to reconfigure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) void vfs_clean_context(struct fs_context *fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 	if (fc->need_free && fc->ops && fc->ops->free)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 		fc->ops->free(fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 	fc->need_free = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 	fc->fs_private = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 	fc->s_fs_info = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 	fc->sb_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 	security_free_mnt_opts(&fc->security);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 	kfree(fc->source);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 	fc->source = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 	fc->purpose = FS_CONTEXT_FOR_RECONFIGURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 	fc->phase = FS_CONTEXT_AWAITING_RECONF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) int finish_clean_context(struct fs_context *fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 	if (fc->phase != FS_CONTEXT_AWAITING_RECONF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 	if (fc->fs_type->init_fs_context)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 		error = fc->fs_type->init_fs_context(fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 		error = legacy_init_fs_context(fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 	if (unlikely(error)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 		fc->phase = FS_CONTEXT_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 	fc->need_free = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 	fc->phase = FS_CONTEXT_RECONF_PARAMS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) }