linux/include/linux/fs_parser.h
<<
>>
Prefs
   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
  13struct path;
  14
  15struct constant_table {
  16        const char      *name;
  17        int             value;
  18};
  19
  20/*
  21 * The type of parameter expected.
  22 */
  23enum fs_parameter_type {
  24        __fs_param_wasnt_defined,
  25        fs_param_is_flag,
  26        fs_param_is_bool,
  27        fs_param_is_u32,
  28        fs_param_is_u32_octal,
  29        fs_param_is_u32_hex,
  30        fs_param_is_s32,
  31        fs_param_is_u64,
  32        fs_param_is_enum,
  33        fs_param_is_string,
  34        fs_param_is_blob,
  35        fs_param_is_blockdev,
  36        fs_param_is_path,
  37        fs_param_is_fd,
  38        nr__fs_parameter_type,
  39};
  40
  41/*
  42 * Specification of the type of value a parameter wants.
  43 *
  44 * Note that the fsparam_flag(), fsparam_string(), fsparam_u32(), ... macros
  45 * should be used to generate elements of this type.
  46 */
  47struct fs_parameter_spec {
  48        const char              *name;
  49        u8                      opt;    /* Option number (returned by fs_parse()) */
  50        enum fs_parameter_type  type:8; /* The desired parameter type */
  51        unsigned short          flags;
  52#define fs_param_v_optional     0x0001  /* The value is optional */
  53#define fs_param_neg_with_no    0x0002  /* "noxxx" is negative param */
  54#define fs_param_neg_with_empty 0x0004  /* "xxx=" is negative param */
  55#define fs_param_deprecated     0x0008  /* The param is deprecated */
  56};
  57
  58struct fs_parameter_enum {
  59        u8              opt;            /* Option number (as fs_parameter_spec::opt) */
  60        char            name[14];
  61        u8              value;
  62};
  63
  64struct fs_parameter_description {
  65        const char      name[16];               /* Name for logging purposes */
  66        const struct fs_parameter_spec *specs;  /* List of param specifications */
  67        const struct fs_parameter_enum *enums;  /* Enum values */
  68};
  69
  70/*
  71 * Result of parse.
  72 */
  73struct fs_parse_result {
  74        bool                    negated;        /* T if param was "noxxx" */
  75        bool                    has_value;      /* T if value supplied to param */
  76        union {
  77                bool            boolean;        /* For spec_bool */
  78                int             int_32;         /* For spec_s32/spec_enum */
  79                unsigned int    uint_32;        /* For spec_u32{,_octal,_hex}/spec_enum */
  80                u64             uint_64;        /* For spec_u64 */
  81        };
  82};
  83
  84extern int fs_parse(struct fs_context *fc,
  85                    const struct fs_parameter_description *desc,
  86                    struct fs_parameter *value,
  87                    struct fs_parse_result *result);
  88extern int fs_lookup_param(struct fs_context *fc,
  89                           struct fs_parameter *param,
  90                           bool want_bdev,
  91                           struct path *_path);
  92
  93extern int __lookup_constant(const struct constant_table tbl[], size_t tbl_size,
  94                             const char *name, int not_found);
  95#define lookup_constant(t, n, nf) __lookup_constant(t, ARRAY_SIZE(t), (n), (nf))
  96
  97#ifdef CONFIG_VALIDATE_FS_PARSER
  98extern bool validate_constant_table(const struct constant_table *tbl, size_t tbl_size,
  99                                    int low, int high, int special);
 100extern bool fs_validate_description(const struct fs_parameter_description *desc);
 101#else
 102static inline bool validate_constant_table(const struct constant_table *tbl, size_t tbl_size,
 103                                           int low, int high, int special)
 104{ return true; }
 105static inline bool fs_validate_description(const struct fs_parameter_description *desc)
 106{ return true; }
 107#endif
 108
 109/*
 110 * Parameter type, name, index and flags element constructors.  Use as:
 111 *
 112 *  fsparam_xxxx("foo", Opt_foo)
 113 *
 114 * If existing helpers are not enough, direct use of __fsparam() would
 115 * work, but any such case is probably a sign that new helper is needed.
 116 * Helpers will remain stable; low-level implementation may change.
 117 */
 118#define __fsparam(TYPE, NAME, OPT, FLAGS) \
 119        { \
 120                .name = NAME, \
 121                .opt = OPT, \
 122                .type = TYPE, \
 123                .flags = FLAGS \
 124        }
 125
 126#define fsparam_flag(NAME, OPT) __fsparam(fs_param_is_flag, NAME, OPT, 0)
 127#define fsparam_flag_no(NAME, OPT) \
 128                                __fsparam(fs_param_is_flag, NAME, OPT, \
 129                                            fs_param_neg_with_no)
 130#define fsparam_bool(NAME, OPT) __fsparam(fs_param_is_bool, NAME, OPT, 0)
 131#define fsparam_u32(NAME, OPT)  __fsparam(fs_param_is_u32, NAME, OPT, 0)
 132#define fsparam_u32oct(NAME, OPT) \
 133                                __fsparam(fs_param_is_u32_octal, NAME, OPT, 0)
 134#define fsparam_u32hex(NAME, OPT) \
 135                                __fsparam(fs_param_is_u32_hex, NAME, OPT, 0)
 136#define fsparam_s32(NAME, OPT)  __fsparam(fs_param_is_s32, NAME, OPT, 0)
 137#define fsparam_u64(NAME, OPT)  __fsparam(fs_param_is_u64, NAME, OPT, 0)
 138#define fsparam_enum(NAME, OPT) __fsparam(fs_param_is_enum, NAME, OPT, 0)
 139#define fsparam_string(NAME, OPT) \
 140                                __fsparam(fs_param_is_string, NAME, OPT, 0)
 141#define fsparam_blob(NAME, OPT) __fsparam(fs_param_is_blob, NAME, OPT, 0)
 142#define fsparam_bdev(NAME, OPT) __fsparam(fs_param_is_blockdev, NAME, OPT, 0)
 143#define fsparam_path(NAME, OPT) __fsparam(fs_param_is_path, NAME, OPT, 0)
 144#define fsparam_fd(NAME, OPT)   __fsparam(fs_param_is_fd, NAME, OPT, 0)
 145
 146
 147#endif /* _LINUX_FS_PARSER_H */
 148