Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-or-later */
0002 /* Filesystem parameter description and parser
0003  *
0004  * Copyright (C) 2018 Red Hat, Inc. All Rights Reserved.
0005  * Written by David Howells (dhowells@redhat.com)
0006  */
0007 
0008 #ifndef _LINUX_FS_PARSER_H
0009 #define _LINUX_FS_PARSER_H
0010 
0011 #include <linux/fs_context.h>
0012 
0013 struct path;
0014 
0015 struct constant_table {
0016     const char  *name;
0017     int     value;
0018 };
0019 
0020 struct fs_parameter_spec;
0021 struct fs_parse_result;
0022 typedef int fs_param_type(struct p_log *,
0023               const struct fs_parameter_spec *,
0024               struct fs_parameter *,
0025               struct fs_parse_result *);
0026 /*
0027  * The type of parameter expected.
0028  */
0029 fs_param_type fs_param_is_bool, fs_param_is_u32, fs_param_is_s32, fs_param_is_u64,
0030     fs_param_is_enum, fs_param_is_string, fs_param_is_blob, fs_param_is_blockdev,
0031     fs_param_is_path, fs_param_is_fd;
0032 
0033 /*
0034  * Specification of the type of value a parameter wants.
0035  *
0036  * Note that the fsparam_flag(), fsparam_string(), fsparam_u32(), ... macros
0037  * should be used to generate elements of this type.
0038  */
0039 struct fs_parameter_spec {
0040     const char      *name;
0041     fs_param_type       *type;  /* The desired parameter type */
0042     u8          opt;    /* Option number (returned by fs_parse()) */
0043     unsigned short      flags;
0044 #define fs_param_neg_with_no    0x0002  /* "noxxx" is negative param */
0045 #define fs_param_can_be_empty   0x0004  /* "xxx=" is allowed */
0046 #define fs_param_deprecated 0x0008  /* The param is deprecated */
0047     const void      *data;
0048 };
0049 
0050 /*
0051  * Result of parse.
0052  */
0053 struct fs_parse_result {
0054     bool            negated;    /* T if param was "noxxx" */
0055     union {
0056         bool        boolean;    /* For spec_bool */
0057         int     int_32;     /* For spec_s32/spec_enum */
0058         unsigned int    uint_32;    /* For spec_u32{,_octal,_hex}/spec_enum */
0059         u64     uint_64;    /* For spec_u64 */
0060     };
0061 };
0062 
0063 extern int __fs_parse(struct p_log *log,
0064             const struct fs_parameter_spec *desc,
0065             struct fs_parameter *value,
0066             struct fs_parse_result *result);
0067 
0068 static inline int fs_parse(struct fs_context *fc,
0069          const struct fs_parameter_spec *desc,
0070          struct fs_parameter *param,
0071          struct fs_parse_result *result)
0072 {
0073     return __fs_parse(&fc->log, desc, param, result);
0074 }
0075 
0076 extern int fs_lookup_param(struct fs_context *fc,
0077                struct fs_parameter *param,
0078                bool want_bdev,
0079                struct path *_path);
0080 
0081 extern int lookup_constant(const struct constant_table tbl[], const char *name, int not_found);
0082 
0083 #ifdef CONFIG_VALIDATE_FS_PARSER
0084 extern bool validate_constant_table(const struct constant_table *tbl, size_t tbl_size,
0085                     int low, int high, int special);
0086 extern bool fs_validate_description(const char *name,
0087                     const struct fs_parameter_spec *desc);
0088 #else
0089 static inline bool validate_constant_table(const struct constant_table *tbl, size_t tbl_size,
0090                        int low, int high, int special)
0091 { return true; }
0092 static inline bool fs_validate_description(const char *name,
0093                        const struct fs_parameter_spec *desc)
0094 { return true; }
0095 #endif
0096 
0097 /*
0098  * Parameter type, name, index and flags element constructors.  Use as:
0099  *
0100  *  fsparam_xxxx("foo", Opt_foo)
0101  *
0102  * If existing helpers are not enough, direct use of __fsparam() would
0103  * work, but any such case is probably a sign that new helper is needed.
0104  * Helpers will remain stable; low-level implementation may change.
0105  */
0106 #define __fsparam(TYPE, NAME, OPT, FLAGS, DATA) \
0107     { \
0108         .name = NAME, \
0109         .opt = OPT, \
0110         .type = TYPE, \
0111         .flags = FLAGS, \
0112         .data = DATA \
0113     }
0114 
0115 #define fsparam_flag(NAME, OPT) __fsparam(NULL, NAME, OPT, 0, NULL)
0116 #define fsparam_flag_no(NAME, OPT) \
0117             __fsparam(NULL, NAME, OPT, fs_param_neg_with_no, NULL)
0118 #define fsparam_bool(NAME, OPT) __fsparam(fs_param_is_bool, NAME, OPT, 0, NULL)
0119 #define fsparam_u32(NAME, OPT)  __fsparam(fs_param_is_u32, NAME, OPT, 0, NULL)
0120 #define fsparam_u32oct(NAME, OPT) \
0121             __fsparam(fs_param_is_u32, NAME, OPT, 0, (void *)8)
0122 #define fsparam_u32hex(NAME, OPT) \
0123             __fsparam(fs_param_is_u32_hex, NAME, OPT, 0, (void *)16)
0124 #define fsparam_s32(NAME, OPT)  __fsparam(fs_param_is_s32, NAME, OPT, 0, NULL)
0125 #define fsparam_u64(NAME, OPT)  __fsparam(fs_param_is_u64, NAME, OPT, 0, NULL)
0126 #define fsparam_enum(NAME, OPT, array)  __fsparam(fs_param_is_enum, NAME, OPT, 0, array)
0127 #define fsparam_string(NAME, OPT) \
0128                 __fsparam(fs_param_is_string, NAME, OPT, 0, NULL)
0129 #define fsparam_blob(NAME, OPT) __fsparam(fs_param_is_blob, NAME, OPT, 0, NULL)
0130 #define fsparam_bdev(NAME, OPT) __fsparam(fs_param_is_blockdev, NAME, OPT, 0, NULL)
0131 #define fsparam_path(NAME, OPT) __fsparam(fs_param_is_path, NAME, OPT, 0, NULL)
0132 #define fsparam_fd(NAME, OPT)   __fsparam(fs_param_is_fd, NAME, OPT, 0, NULL)
0133 
0134 #endif /* _LINUX_FS_PARSER_H */