Line data Source code
1 : /* SPDX-License-Identifier: GPL-2.0 */ 2 : #ifndef __LINUX_TEXTSEARCH_H 3 : #define __LINUX_TEXTSEARCH_H 4 : 5 : #include <linux/types.h> 6 : #include <linux/list.h> 7 : #include <linux/kernel.h> 8 : #include <linux/err.h> 9 : #include <linux/slab.h> 10 : 11 : struct module; 12 : 13 : struct ts_config; 14 : 15 : #define TS_AUTOLOAD 1 /* Automatically load textsearch modules when needed */ 16 : #define TS_IGNORECASE 2 /* Searches string case insensitively */ 17 : 18 : /** 19 : * struct ts_state - search state 20 : * @offset: offset for next match 21 : * @cb: control buffer, for persistent variables of get_next_block() 22 : */ 23 : struct ts_state 24 : { 25 : unsigned int offset; 26 : char cb[48]; 27 : }; 28 : 29 : /** 30 : * struct ts_ops - search module operations 31 : * @name: name of search algorithm 32 : * @init: initialization function to prepare a search 33 : * @find: find the next occurrence of the pattern 34 : * @destroy: destroy algorithm specific parts of a search configuration 35 : * @get_pattern: return head of pattern 36 : * @get_pattern_len: return length of pattern 37 : * @owner: module reference to algorithm 38 : */ 39 : struct ts_ops 40 : { 41 : const char *name; 42 : struct ts_config * (*init)(const void *, unsigned int, gfp_t, int); 43 : unsigned int (*find)(struct ts_config *, 44 : struct ts_state *); 45 : void (*destroy)(struct ts_config *); 46 : void * (*get_pattern)(struct ts_config *); 47 : unsigned int (*get_pattern_len)(struct ts_config *); 48 : struct module *owner; 49 : struct list_head list; 50 : }; 51 : 52 : /** 53 : * struct ts_config - search configuration 54 : * @ops: operations of chosen algorithm 55 : * @flags: flags 56 : * @get_next_block: callback to fetch the next block to search in 57 : * @finish: callback to finalize a search 58 : */ 59 : struct ts_config 60 : { 61 : struct ts_ops *ops; 62 : int flags; 63 : 64 : /** 65 : * @get_next_block: fetch next block of data 66 : * @consumed: number of bytes consumed by the caller 67 : * @dst: destination buffer 68 : * @conf: search configuration 69 : * @state: search state 70 : * 71 : * Called repeatedly until 0 is returned. Must assign the 72 : * head of the next block of data to &*dst and return the length 73 : * of the block or 0 if at the end. consumed == 0 indicates 74 : * a new search. May store/read persistent values in state->cb. 75 : */ 76 : unsigned int (*get_next_block)(unsigned int consumed, 77 : const u8 **dst, 78 : struct ts_config *conf, 79 : struct ts_state *state); 80 : 81 : /** 82 : * @finish: finalize/clean a series of get_next_block() calls 83 : * @conf: search configuration 84 : * @state: search state 85 : * 86 : * Called after the last use of get_next_block(), may be used 87 : * to cleanup any leftovers. 88 : */ 89 : void (*finish)(struct ts_config *conf, 90 : struct ts_state *state); 91 : }; 92 : 93 : /** 94 : * textsearch_next - continue searching for a pattern 95 : * @conf: search configuration 96 : * @state: search state 97 : * 98 : * Continues a search looking for more occurrences of the pattern. 99 : * textsearch_find() must be called to find the first occurrence 100 : * in order to reset the state. 101 : * 102 : * Returns the position of the next occurrence of the pattern or 103 : * UINT_MAX if not match was found. 104 : */ 105 0 : static inline unsigned int textsearch_next(struct ts_config *conf, 106 : struct ts_state *state) 107 : { 108 0 : unsigned int ret = conf->ops->find(conf, state); 109 : 110 0 : if (conf->finish) 111 0 : conf->finish(conf, state); 112 : 113 0 : return ret; 114 : } 115 : 116 : /** 117 : * textsearch_find - start searching for a pattern 118 : * @conf: search configuration 119 : * @state: search state 120 : * 121 : * Returns the position of first occurrence of the pattern or 122 : * UINT_MAX if no match was found. 123 : */ 124 0 : static inline unsigned int textsearch_find(struct ts_config *conf, 125 : struct ts_state *state) 126 : { 127 0 : state->offset = 0; 128 0 : return textsearch_next(conf, state); 129 : } 130 : 131 : /** 132 : * textsearch_get_pattern - return head of the pattern 133 : * @conf: search configuration 134 : */ 135 : static inline void *textsearch_get_pattern(struct ts_config *conf) 136 : { 137 : return conf->ops->get_pattern(conf); 138 : } 139 : 140 : /** 141 : * textsearch_get_pattern_len - return length of the pattern 142 : * @conf: search configuration 143 : */ 144 : static inline unsigned int textsearch_get_pattern_len(struct ts_config *conf) 145 : { 146 : return conf->ops->get_pattern_len(conf); 147 : } 148 : 149 : extern int textsearch_register(struct ts_ops *); 150 : extern int textsearch_unregister(struct ts_ops *); 151 : extern struct ts_config *textsearch_prepare(const char *, const void *, 152 : unsigned int, gfp_t, int); 153 : extern void textsearch_destroy(struct ts_config *conf); 154 : extern unsigned int textsearch_find_continuous(struct ts_config *, 155 : struct ts_state *, 156 : const void *, unsigned int); 157 : 158 : 159 : #define TS_PRIV_ALIGNTO 8 160 : #define TS_PRIV_ALIGN(len) (((len) + TS_PRIV_ALIGNTO-1) & ~(TS_PRIV_ALIGNTO-1)) 161 : 162 : static inline struct ts_config *alloc_ts_config(size_t payload, 163 : gfp_t gfp_mask) 164 : { 165 : struct ts_config *conf; 166 : 167 : conf = kzalloc(TS_PRIV_ALIGN(sizeof(*conf)) + payload, gfp_mask); 168 : if (conf == NULL) 169 : return ERR_PTR(-ENOMEM); 170 : 171 : return conf; 172 : } 173 : 174 : static inline void *ts_config_priv(struct ts_config *conf) 175 : { 176 : return ((u8 *) conf + TS_PRIV_ALIGN(sizeof(struct ts_config))); 177 : } 178 : 179 : #endif