Commit 328de528 authored by Al Viro's avatar Al Viro
Browse files

turn fs_param_is_... into functions



Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 48ce73b1
Loading
Loading
Loading
Loading
+124 −104
Original line number Diff line number Diff line
@@ -48,7 +48,7 @@ EXPORT_SYMBOL(lookup_constant);

static inline bool is_flag(const struct fs_parameter_spec *p)
{
	return p->type == fs_param_is_flag;
	return p->type == NULL;
}

static const struct fs_parameter_spec *fs_lookup_key(
@@ -106,8 +106,6 @@ int __fs_parse(struct p_log *log,
	     struct fs_parse_result *result)
{
	const struct fs_parameter_spec *p;
	const struct constant_table *e;
	int ret = -ENOPARAM, b;

	result->uint_64 = 0;

@@ -121,96 +119,17 @@ int __fs_parse(struct p_log *log,
	/* Try to turn the type we were given into the type desired by the
	 * parameter and give an error if we can't.
	 */
	switch (p->type) {
	case __fs_param_wasnt_defined:
		return -EINVAL;
	case fs_param_is_flag:
	if (is_flag(p)) {
		if (param->type != fs_value_is_flag)
			return inval_plog(log, "Unexpected value for '%s'",
				      param->key);
		result->boolean = !result->negated;
		goto okay;
	case fs_param_is_bool:
		if (param->type != fs_value_is_string)
			goto bad_value;
		b = lookup_constant(bool_names, param->string, -1);
		if (b == -1)
			goto bad_value;
		result->boolean = b;
		goto okay;
	case fs_param_is_u32:
		if (param->type != fs_value_is_string)
			goto bad_value;
		ret = kstrtouint(param->string, 0, &result->uint_32);
		goto maybe_okay;
	case fs_param_is_u32_octal:
		if (param->type != fs_value_is_string)
			goto bad_value;
		ret = kstrtouint(param->string, 8, &result->uint_32);
		goto maybe_okay;
	case fs_param_is_u32_hex:
		if (param->type != fs_value_is_string)
			goto bad_value;
		ret = kstrtouint(param->string, 16, &result->uint_32);
		goto maybe_okay;
	case fs_param_is_s32:
		if (param->type != fs_value_is_string)
			goto bad_value;
		ret = kstrtoint(param->string, 0, &result->int_32);
		goto maybe_okay;
	case fs_param_is_u64:
		if (param->type != fs_value_is_string)
			goto bad_value;
		ret = kstrtoull(param->string, 0, &result->uint_64);
		goto maybe_okay;
	case fs_param_is_enum:
		if (param->type != fs_value_is_string)
			goto bad_value;
		e = __lookup_constant(p->data, param->string);
		if (e) {
			result->uint_32 = e->value;
			goto okay;
		}
		goto bad_value;
	case fs_param_is_string:
		if (param->type != fs_value_is_string || !*param->string)
			goto bad_value;
		goto okay;
	case fs_param_is_blob:
		if (param->type != fs_value_is_blob)
			goto bad_value;
		goto okay;
	case fs_param_is_fd: {
		switch (param->type) {
		case fs_value_is_string:
			ret = kstrtouint(param->string, 0, &result->uint_32);
			break;
		case fs_value_is_file:
			result->uint_32 = param->dirfd;
			ret = 0;
		default:
			goto bad_value;
		}

		if (result->uint_32 > INT_MAX)
			goto bad_value;
		goto maybe_okay;
	}
	case fs_param_is_blockdev:
	case fs_param_is_path:
		goto okay;
	default:
		BUG();
	} else  {
		int ret = p->type(log, p, param, result);
		if (ret)
			return ret;
	}

maybe_okay:
	if (ret < 0)
		goto bad_value;
okay:
	return p->opt;

bad_value:
	return inval_plog(log, "Bad value for '%s'", param->key);
}
EXPORT_SYMBOL(__fs_parse);

@@ -270,6 +189,124 @@ out:
}
EXPORT_SYMBOL(fs_lookup_param);

int fs_param_bad_value(struct p_log *log, struct fs_parameter *param)
{
	return inval_plog(log, "Bad value for '%s'", param->key);
}

int fs_param_is_bool(struct p_log *log, const struct fs_parameter_spec *p,
		     struct fs_parameter *param, struct fs_parse_result *result)
{
	int b;
	if (param->type != fs_value_is_string)
		return fs_param_bad_value(log, param);
	b = lookup_constant(bool_names, param->string, -1);
	if (b == -1)
		return fs_param_bad_value(log, param);
	result->boolean = b;
	return 0;
}
EXPORT_SYMBOL(fs_param_is_bool);

int fs_param_is_u32(struct p_log *log, const struct fs_parameter_spec *p,
		    struct fs_parameter *param, struct fs_parse_result *result)
{
	int base = (unsigned long)p->data;
	if (param->type != fs_value_is_string ||
	    kstrtouint(param->string, base, &result->uint_32) < 0)
		return fs_param_bad_value(log, param);
	return 0;
}
EXPORT_SYMBOL(fs_param_is_u32);

int fs_param_is_s32(struct p_log *log, const struct fs_parameter_spec *p,
		    struct fs_parameter *param, struct fs_parse_result *result)
{
	if (param->type != fs_value_is_string ||
	    kstrtoint(param->string, 0, &result->int_32) < 0)
		return fs_param_bad_value(log, param);
	return 0;
}
EXPORT_SYMBOL(fs_param_is_s32);

int fs_param_is_u64(struct p_log *log, const struct fs_parameter_spec *p,
		    struct fs_parameter *param, struct fs_parse_result *result)
{
	if (param->type != fs_value_is_string ||
	    kstrtoull(param->string, 0, &result->uint_64) < 0)
		return fs_param_bad_value(log, param);
	return 0;
}
EXPORT_SYMBOL(fs_param_is_u64);

int fs_param_is_enum(struct p_log *log, const struct fs_parameter_spec *p,
		     struct fs_parameter *param, struct fs_parse_result *result)
{
	const struct constant_table *c;
	if (param->type != fs_value_is_string)
		return fs_param_bad_value(log, param);
	c = __lookup_constant(p->data, param->string);
	if (!c)
		return fs_param_bad_value(log, param);
	result->uint_32 = c->value;
	return 0;
}
EXPORT_SYMBOL(fs_param_is_enum);

int fs_param_is_string(struct p_log *log, const struct fs_parameter_spec *p,
		       struct fs_parameter *param, struct fs_parse_result *result)
{
	if (param->type != fs_value_is_string || !*param->string)
		return fs_param_bad_value(log, param);
	return 0;
}
EXPORT_SYMBOL(fs_param_is_string);

int fs_param_is_blob(struct p_log *log, const struct fs_parameter_spec *p,
		     struct fs_parameter *param, struct fs_parse_result *result)
{
	if (param->type != fs_value_is_blob)
		return fs_param_bad_value(log, param);
	return 0;
}
EXPORT_SYMBOL(fs_param_is_blob);

int fs_param_is_fd(struct p_log *log, const struct fs_parameter_spec *p,
		  struct fs_parameter *param, struct fs_parse_result *result)
{
	switch (param->type) {
	case fs_value_is_string:
		if (kstrtouint(param->string, 0, &result->uint_32) < 0)
			break;
		if (result->uint_32 <= INT_MAX)
			return 0;
		break;
	case fs_value_is_file:
		result->uint_32 = param->dirfd;
		if (result->uint_32 <= INT_MAX)
			return 0;
		break;
	default:
		break;
	}
	return fs_param_bad_value(log, param);
}
EXPORT_SYMBOL(fs_param_is_fd);

int fs_param_is_blockdev(struct p_log *log, const struct fs_parameter_spec *p,
		  struct fs_parameter *param, struct fs_parse_result *result)
{
	return 0;
}
EXPORT_SYMBOL(fs_param_is_blockdev);

int fs_param_is_path(struct p_log *log, const struct fs_parameter_spec *p,
		     struct fs_parameter *param, struct fs_parse_result *result)
{
	return 0;
}
EXPORT_SYMBOL(fs_param_is_path);

#ifdef CONFIG_VALIDATE_FS_PARSER
/**
 * validate_constant_table - Validate a constant table
@@ -334,23 +371,6 @@ bool fs_validate_description(const char *name,
	pr_notice("*** VALIDATE %s ***\n", name);

	for (param = desc; param->name; param++) {
		enum fs_parameter_type t = param->type;

		/* Check that the type is in range */
		if (t == __fs_param_wasnt_defined ||
		    t >= nr__fs_parameter_type) {
			pr_err("VALIDATE %s: PARAM[%s] Bad type %u\n",
			       name, param->name, t);
			good = false;
		} else if (t == fs_param_is_enum) {
			const struct constant_table *e = param->data;
			if (!e || !e->name) {
				pr_err("VALIDATE %s: PARAM[%s] enum with no values\n",
				       name, param->name);
				good = false;
			}
		}

		/* Check for duplicate parameter names */
		for (p2 = desc; p2 < param; p2++) {
			if (strcmp(param->name, p2->name) == 0) {
+1 −1
Original line number Diff line number Diff line
@@ -129,7 +129,7 @@ static const struct fs_parameter_spec nfs_fs_parameters[] = {
	fsparam_flag_no("fsc",		Opt_fscache_flag),
	fsparam_string("fsc",		Opt_fscache),
	fsparam_flag  ("hard",		Opt_hard),
	__fsparam(fs_param_is_flag, "intr",		Opt_intr,
	__fsparam(NULL, "intr",		Opt_intr,
		  fs_param_neg_with_no|fs_param_deprecated, NULL),
	fsparam_enum  ("local_lock",	Opt_local_lock, nfs_param_enums_local_lock),
	fsparam_flag_no("lock",		Opt_lock),
+14 −24
Original line number Diff line number Diff line
@@ -17,26 +17,18 @@ struct constant_table {
	int		value;
};

struct fs_parameter_spec;
struct fs_parse_result;
typedef int fs_param_type(struct p_log *,
			  const struct fs_parameter_spec *,
			  struct fs_parameter *,
			  struct fs_parse_result *);
/*
 * The type of parameter expected.
 */
enum fs_parameter_type {
	__fs_param_wasnt_defined,
	fs_param_is_flag,
	fs_param_is_bool,
	fs_param_is_u32,
	fs_param_is_u32_octal,
	fs_param_is_u32_hex,
	fs_param_is_s32,
	fs_param_is_u64,
	fs_param_is_enum,
	fs_param_is_string,
	fs_param_is_blob,
	fs_param_is_blockdev,
	fs_param_is_path,
	fs_param_is_fd,
	nr__fs_parameter_type,
};
fs_param_type fs_param_is_bool, fs_param_is_u32, fs_param_is_s32, fs_param_is_u64,
	fs_param_is_enum, fs_param_is_string, fs_param_is_blob, fs_param_is_blockdev,
	fs_param_is_path, fs_param_is_fd;

/*
 * Specification of the type of value a parameter wants.
@@ -46,8 +38,8 @@ enum fs_parameter_type {
 */
struct fs_parameter_spec {
	const char		*name;
	fs_param_type		*type;	/* The desired parameter type */
	u8			opt;	/* Option number (returned by fs_parse()) */
	enum fs_parameter_type	type:8;	/* The desired parameter type */
	unsigned short		flags;
#define fs_param_neg_with_no	0x0002	/* "noxxx" is negative param */
#define fs_param_neg_with_empty	0x0004	/* "xxx=" is negative param */
@@ -120,16 +112,15 @@ static inline bool fs_validate_description(const char *name,
		.data = DATA \
	}

#define fsparam_flag(NAME, OPT)	__fsparam(fs_param_is_flag, NAME, OPT, 0, NULL)
#define fsparam_flag(NAME, OPT)	__fsparam(NULL, NAME, OPT, 0, NULL)
#define fsparam_flag_no(NAME, OPT) \
				__fsparam(fs_param_is_flag, NAME, OPT, \
					    fs_param_neg_with_no, NULL)
			__fsparam(NULL, NAME, OPT, fs_param_neg_with_no, NULL)
#define fsparam_bool(NAME, OPT)	__fsparam(fs_param_is_bool, NAME, OPT, 0, NULL)
#define fsparam_u32(NAME, OPT)	__fsparam(fs_param_is_u32, NAME, OPT, 0, NULL)
#define fsparam_u32oct(NAME, OPT) \
				__fsparam(fs_param_is_u32_octal, NAME, OPT, 0, NULL)
			__fsparam(fs_param_is_u32, NAME, OPT, 0, (void *)8)
#define fsparam_u32hex(NAME, OPT) \
				__fsparam(fs_param_is_u32_hex, NAME, OPT, 0, NULL)
			__fsparam(fs_param_is_u32_hex, NAME, OPT, 0, (void *16))
#define fsparam_s32(NAME, OPT)	__fsparam(fs_param_is_s32, NAME, OPT, 0, NULL)
#define fsparam_u64(NAME, OPT)	__fsparam(fs_param_is_u64, NAME, OPT, 0, NULL)
#define fsparam_enum(NAME, OPT, array)	__fsparam(fs_param_is_enum, NAME, OPT, 0, array)
@@ -140,5 +131,4 @@ static inline bool fs_validate_description(const char *name,
#define fsparam_path(NAME, OPT)	__fsparam(fs_param_is_path, NAME, OPT, 0, NULL)
#define fsparam_fd(NAME, OPT)	__fsparam(fs_param_is_fd, NAME, OPT, 0, NULL)


#endif /* _LINUX_FS_PARSER_H */