1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ |
2 | /* Filesystem parameter description and parser |
3 | * |
4 | * Copyright (C) 2018 Red Hat, Inc. All Rights Reserved. |
5 | * Written by David Howells (dhowells@redhat.com) |
6 | */ |
7 | |
8 | #ifndef _LINUX_FS_PARSER_H |
9 | #define _LINUX_FS_PARSER_H |
10 | |
11 | #include <linux/fs_context.h> |
12 | |
13 | struct path; |
14 | |
15 | struct constant_table { |
16 | const char *name; |
17 | int value; |
18 | }; |
19 | |
20 | struct fs_parameter_spec; |
21 | struct fs_parse_result; |
22 | typedef int fs_param_type(struct p_log *, |
23 | const struct fs_parameter_spec *, |
24 | struct fs_parameter *, |
25 | struct fs_parse_result *); |
26 | /* |
27 | * The type of parameter expected. |
28 | */ |
29 | fs_param_type fs_param_is_bool, fs_param_is_u32, fs_param_is_s32, fs_param_is_u64, |
30 | fs_param_is_enum, fs_param_is_string, fs_param_is_blob, fs_param_is_blockdev, |
31 | fs_param_is_path, fs_param_is_fd; |
32 | |
33 | /* |
34 | * Specification of the type of value a parameter wants. |
35 | * |
36 | * Note that the fsparam_flag(), fsparam_string(), fsparam_u32(), ... macros |
37 | * should be used to generate elements of this type. |
38 | */ |
39 | struct fs_parameter_spec { |
40 | const char *name; |
41 | fs_param_type *type; /* The desired parameter type */ |
42 | u8 opt; /* Option number (returned by fs_parse()) */ |
43 | unsigned short flags; |
44 | #define fs_param_neg_with_no 0x0002 /* "noxxx" is negative param */ |
45 | #define fs_param_can_be_empty 0x0004 /* "xxx=" is allowed */ |
46 | #define fs_param_deprecated 0x0008 /* The param is deprecated */ |
47 | const void *data; |
48 | }; |
49 | |
50 | /* |
51 | * Result of parse. |
52 | */ |
53 | struct fs_parse_result { |
54 | bool negated; /* T if param was "noxxx" */ |
55 | union { |
56 | bool boolean; /* For spec_bool */ |
57 | int int_32; /* For spec_s32/spec_enum */ |
58 | unsigned int uint_32; /* For spec_u32{,_octal,_hex}/spec_enum */ |
59 | u64 uint_64; /* For spec_u64 */ |
60 | }; |
61 | }; |
62 | |
63 | extern int __fs_parse(struct p_log *log, |
64 | const struct fs_parameter_spec *desc, |
65 | struct fs_parameter *value, |
66 | struct fs_parse_result *result); |
67 | |
68 | static inline int fs_parse(struct fs_context *fc, |
69 | const struct fs_parameter_spec *desc, |
70 | struct fs_parameter *param, |
71 | struct fs_parse_result *result) |
72 | { |
73 | return __fs_parse(log: &fc->log, desc, value: param, result); |
74 | } |
75 | |
76 | extern int fs_lookup_param(struct fs_context *fc, |
77 | struct fs_parameter *param, |
78 | bool want_bdev, |
79 | unsigned int flags, |
80 | struct path *_path); |
81 | |
82 | extern int lookup_constant(const struct constant_table tbl[], const char *name, int not_found); |
83 | |
84 | #ifdef CONFIG_VALIDATE_FS_PARSER |
85 | extern bool validate_constant_table(const struct constant_table *tbl, size_t tbl_size, |
86 | int low, int high, int special); |
87 | extern bool fs_validate_description(const char *name, |
88 | const struct fs_parameter_spec *desc); |
89 | #else |
90 | static inline bool validate_constant_table(const struct constant_table *tbl, size_t tbl_size, |
91 | int low, int high, int special) |
92 | { return true; } |
93 | static inline bool fs_validate_description(const char *name, |
94 | const struct fs_parameter_spec *desc) |
95 | { return true; } |
96 | #endif |
97 | |
98 | /* |
99 | * Parameter type, name, index and flags element constructors. Use as: |
100 | * |
101 | * fsparam_xxxx("foo", Opt_foo) |
102 | * |
103 | * If existing helpers are not enough, direct use of __fsparam() would |
104 | * work, but any such case is probably a sign that new helper is needed. |
105 | * Helpers will remain stable; low-level implementation may change. |
106 | */ |
107 | #define __fsparam(TYPE, NAME, OPT, FLAGS, DATA) \ |
108 | { \ |
109 | .name = NAME, \ |
110 | .opt = OPT, \ |
111 | .type = TYPE, \ |
112 | .flags = FLAGS, \ |
113 | .data = DATA \ |
114 | } |
115 | |
116 | #define fsparam_flag(NAME, OPT) __fsparam(NULL, NAME, OPT, 0, NULL) |
117 | #define fsparam_flag_no(NAME, OPT) \ |
118 | __fsparam(NULL, NAME, OPT, fs_param_neg_with_no, NULL) |
119 | #define fsparam_bool(NAME, OPT) __fsparam(fs_param_is_bool, NAME, OPT, 0, NULL) |
120 | #define fsparam_u32(NAME, OPT) __fsparam(fs_param_is_u32, NAME, OPT, 0, NULL) |
121 | #define fsparam_u32oct(NAME, OPT) \ |
122 | __fsparam(fs_param_is_u32, NAME, OPT, 0, (void *)8) |
123 | #define fsparam_u32hex(NAME, OPT) \ |
124 | __fsparam(fs_param_is_u32_hex, NAME, OPT, 0, (void *)16) |
125 | #define fsparam_s32(NAME, OPT) __fsparam(fs_param_is_s32, NAME, OPT, 0, NULL) |
126 | #define fsparam_u64(NAME, OPT) __fsparam(fs_param_is_u64, NAME, OPT, 0, NULL) |
127 | #define fsparam_enum(NAME, OPT, array) __fsparam(fs_param_is_enum, NAME, OPT, 0, array) |
128 | #define fsparam_string(NAME, OPT) \ |
129 | __fsparam(fs_param_is_string, NAME, OPT, 0, NULL) |
130 | #define fsparam_blob(NAME, OPT) __fsparam(fs_param_is_blob, NAME, OPT, 0, NULL) |
131 | #define fsparam_bdev(NAME, OPT) __fsparam(fs_param_is_blockdev, NAME, OPT, 0, NULL) |
132 | #define fsparam_path(NAME, OPT) __fsparam(fs_param_is_path, NAME, OPT, 0, NULL) |
133 | #define fsparam_fd(NAME, OPT) __fsparam(fs_param_is_fd, NAME, OPT, 0, NULL) |
134 | |
135 | #endif /* _LINUX_FS_PARSER_H */ |
136 | |